8.4.2 实现对比较运算符的完全支持(2)
示例说明
注意普通版本operator>()函数的原型所处的位置。该原型需要跟在类定义后面,因为它要引用CBox对象。如果将其放在类定义前面,则将不能编译该示例,因为那时CBox类型还没有定义。
有一种将其放在程序文件开头#include语句后面的方法:使用未完成的类声明,也称为类类型的前向声明。这样该函数的原型就可以放在类定义之前,声明语句如下所示:
- class CBox; // Incomplete class declaration
- inline bool operator < (const double& value, const CBox& aBox); // Prototype
前向声明告诉编译器CBox是一个类,这足以使编译器正确处理第二行的函数原型,因为它现在知道CBox是后面将要指定的用户定义类型。
如果有两个类,而每个类都有一个指针成员指向另一个类的对象,在此类情形中同样需要上述机制。这两个类都要求首先声明另一个类,通过使用未完成的类声明就可以打破这样的僵局。
注意:前向声明可以用于类类型和enum类型。例如:
- enum class Suit;
即使还没有定义enum类型,这个前向声明也允许在该语句后使用Suit enum来声明变量。但是在提供该enum的完整定义之前,不能引用enum类型的枚举值。
这个示例的输出如下:
- Constructor called.
- Constructor called.
- Constructor called.
- mediumBox is not equal to smallBox
- mediumBox is bigger than smallBox
- otherBox is greater than or equal to smallBox
- otherBox is smaller than mediumBox
- mediumBox capacity is more than 50
- smallBox capacity is not more than 10
- Destructor called.
- Destructor called.
- Destructor called.
在声明CBox对象而输出的构造函数消息之后是if语句的输出,每条语句都像我们预期的那样工作。其中第一个语句调用了operator!=()函数,它是由编译器从utility头文件提供的模板中生成的。模板需要类中有==运算符函数的定义。
输出结果说明模板生成的所有运算符函数都是有效的。目前,我们把两个运算符函数都定义为类的普通成员函数,因为它们都只需要访问公有的Volume()函数,该函数为pulic。
任何类类型的比较运算符都可以用这里演示的方式来实现,它们仅在细节方面有些不同,这取决于对象的本质。
- enum class Suit{Clubs, Diamonds, Hearts, Spades};