算术操作符和关系操作符

来源:互联网 发布:免费源码购买 编辑:程序博客网 时间:2024/05/22 23:48
一般而言,将算术和关系操作符定义为非成员函数,像下面给出的Sales_item 加法操作符一样:

// assumes that both objects refer to the same isbn

Sales_item operator+(const Sales_item& lhs, const Sales_item& rhs)

{

Sales_item ret(lhs); // copy lhs into a local object that we'll return

ret += rhs; // add in the contents of rhs

return ret; // return ret by value

}

加法操作符并不改变操作符的状态,操作符是对 const 对象的引用;相反,它产生并返回一个新的 Sales_item 对象,该对象初始化为 lhs 的副本。我们使用 Sales_item 的复合赋值操作符来加入 rhs 的值。


注意,为了与内置操作符保持一致,加法返回一个右值,而不是一个引用。


算术操作符通常产生一个新值,该值是两个操作数的计算结果,它不同于任一操作数且在一个局部变量中计算,返回对那个变量的引用是一个运行时错误。既定义了算术操作符又定义了相关复合赋值操作符的类,一般应使用复合赋值实现算术操作符。


根据复合赋值操作符(如 +=)来实现算术操作符(如 +),比其他方式更简单且更有效。例如,我们的 Sales_item 操作符。如果我们调用 += 来实现 +,则可以不必创建和撤销一个临时量来保存 + 的结果。


相等操作符

通常,C++ 中的类使用相等操作符表示对象是等价的。即,它们通常比较每个数据成员,如果所有对应成员都相同,则认为两个对象相等。与这一设计原则一致,Sales_item 的相等操作符应比较 isbn 以及销售数据:

inline bool operator==(const Sales_item &lhs, const Sales_item &rhs)

{

// must be made a friend of Sales_item

return lhs.units_sold == rhs.units_sold &&

lhs.revenue == rhs.revenue &&

lhs.same_isbn(rhs);

}

inline bool operator!=(const Sales_item &lhs, const Sales_item &rhs)

{

return !(lhs == rhs); // != defined in terms of operator==

}

这些函数的定义并不重要,重要的是这些函数所包含的设计原则:

• 如果类定义了 == 操作符,该操作符的含义是两个对象包含同样的数据。
• 如果类具有一个操作,能确定该类型的两个对象是否相等,通常将该函数定义为 operator== 而不是创造命名函数。用户将习惯于用 == 来比较对象,而且这样做比记住新名字更容易。
• 如果类定义了 operator==,它也应该定义 operator!=。用户会期待如果可以用某个操作符,则另一个也存在。

• 相等和不操作符一般应该相互联系起来定义,让一个操作符完成比较对象的实际工作,而另一个操作符只是调用前者。


定义了 operator== 的类更容易与标准库一起使用。有些算法,如 find,默认使用 == 操作符,如果类定义了 ==,则这些算法可以无须任何特殊处理而用于该类类型。


关系操作符

定义了相等操作符的类一般也具有关系操作符。尤其是,因为关联容器和某些算法使用小于操作符,所以定义 operator< 可能相当有用。

我们也许认为 Sales_item 类应该支持关系操作符,但恰恰相反,它很可能不应该支持关系操作符,原因有些微妙,值得了解。

正如第十五章将要介绍的,我们可能想要使用关联容器来保存 Sales_item事务。将对象放在容器中时,我们希望它们按 ISBN 排序,而不会关心两个记录中的销售数据是否不同。但是,如果将 operator< 定义为对 isbn 的比较,该定义将与前面 == 的定义不相容。如果有两个针对同一 ISBN 的事务,其中任意一个都不会小于另一个,然而,如果这两个对象中的销售数据不同,则它们就不相等。但是,一般说来,如果有两个对象,其中任意一个都不小于另一个,则认为它们相等。

因为 < 的逻辑定义与 == 的逻辑定义不一致,所以根本不定义 < 会更好。第十五章将会介绍想要将 Sales_items 对象存储到关联容器中时,怎样使用单独的命名函数来比较 Sales_items 对象。关联容器以及某些算法,使用默认 < 操作符。一般而言,关系操作符,诸如相等操作符,应定义为非成员函数。
0 0
原创粉丝点击