算数和关系运算符
1.算数运算符
通常情况下,我们把算数和关系运算符定义成非成员函数,因为一般来说算数和关系运算符对象都是对称的,可以左右互换;并且由于这些运算符不需要改变对象的状态,因此参数应设置为常量引用。
一般来说,算数运算符也会定义一个对应的复合运算符。通常情况下应该使用复合运算符形式来实现算数运算符。
如:Sales_data的加号运算符
//Sales_data类
class Sales_data {
friend istream& operator>>(istream& is, Sales_data&);
friend ostream& operator<<(ostream& os, Sales_data&);
friend bool operator==(const Sales_data&, const Sales_data&);
friend Sales_data operator+(Sales_data&, const Sales_data&);
public:
Sales_data(const string& s) :
_bookNo(s), _sold(0), _revenue(0) {}
Sales_data() : Sales_data("x") {}
Sales_data& operator+=(const Sales_data&);
bool operator<(const Sales_data &);
string isbn() const {
return _bookNo;
}
double averPrice() const {
return _revenue / _sold;
}
private:
string _bookNo; //国际标准书号
unsigned _sold; //销售数量
double _revenue; //收入
};
Sales_data& Sales_data::operator+=(const Sales_data &rhs) {
if (isbn() == rhs.isbn()) {
_sold += rhs._sold;
_revenue += rhs._sold;
}
return *this;
}
Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs) {
Sales_data ret(lhs);
ret += rhs;
return ret;
}
2.相等运算符
相等运算符的设计准则:
- 如果一个类含有判断两个对象是否相等的操作,显然应该把函数定义成operator==而不是普通命名的函数。
- 如果类定义了operator==,则该类也应该定义operator!=,反之亦然。
- 相等运算符和不相等运算符的一个应该把工作委托给另一个,这意味着其中一个运算符应该负责实际比较对象的工作,而另一个只是调用哪个真正工作的运算符。
如:Sales_data的==和!=运算符:
bool operator==(const Sales_data &lhs, const Sales_data &rhs) {
return lhs.isbn() == rhs.isbn() &&
lhs._sold == rhs._sold &&
lhs._revenue == rhs._revenue;
}
bool operator!=(const Sales_data &rhs, const Sales_data &rhs) {
return !(lhs == rhs);
}
3.关系运算符
关系运算符的准则:
- 两个关键字不能同时小于等于对方;如果k1小于等于k2,那么k2不能小于等于k1
- 如果k1小于等于k2,且k2小于等于k3,那么k1必须小于等于k3
- 如果存在两个关键字,任何一个都不小于等于另一个,那么我们称这两个关键字是等价的。如果k1等价于k2,且k2等价于k3,那么k1等价于k3.
- 如果类同时也含有==运算符的话,则定义的关系应与相等运算符保持一致。特别是如果两个对象是!=的,那么一个对象应该小于另外一个。
例如:Sales_data的按版本号排序
bool operator<(const Sales_data &rhs) {
return isbn() < rhs.isbn();
}
该函数通过比较ISBN号来实现对两个对象的比较。然而,尽管提供的顺序符合要求,但函数得到的结果与我们定义的==不一致,不满足要求2.
如果两笔交易的ISBN号相同但销售数量和收入不同经比较是不相等的,但实际情况是,任何一个都不比另一个情况小,如果任意一个都不比另一个小按道理来说应该是相等的。
因此,对于Sales_data类来说,不存在一种逻辑可靠的<定义,这个类不定义<运算符更好。如果存在唯一一种逻辑可靠的<定义,则应该考虑为这个类定义<运算符。如果类同时包含==,则当且仅当<的定义和相等运算符产生的结果一致时才定义<运算符。