1,概述
(1)如前一节所述,一般应将算术操作符和关系操作符定义为类的友元函数;
(2)编译器不会默认合成算术操作符和关系操作符,所以你如果不定义这些操作符,就没有办法在类对象上使用它们,这一点与赋值操作符不一样。
会默认合成且可以重载的操作符只有如下几个:
赋值操作符(=)
取地址符(&)
逗号(,)
与操作符(&&)
或操作符(||)
并且除了赋值操作符以外,其他4个操作符都最好不要重载。
2,算术运算符
(1)由于复合赋值运算符应当被定义为成员函数,所以可以也应当用复合赋值运算符来实现算术运算符的功能,比如通过调用“+=”来实现“+”的功能;
(2)由于内置的算术运算符返回的是右值而不是引用,所以也应当让重载的算术运算符(比如“+”)返回右值,而不是引用;事实上,加法操作产生一个新值,我们可以用函数定义中的一个局部变量来存储这个新值,但函数不应该返回局部变量的引用,因为函数调用结束后,该局部变量就被收回了。
(3)以加法为例,算术运算符的重载的通用格式如下:
friend ClassType operator+ (const ClassType &lhs, const ClassType &rhs);
用“+=”来实现“+”的示例:
// 复合赋值操作符,成员函数
Sales_item2& Sales_item2::operator+=(const Sales_item2& book)
{
this->units_sold += book.units_sold;
this->revenue += book.revenue;
return *this;
}
// 算术操作符,友员函数
Sales_item2 operator+ (const Sales_item2 &lhr, const Sales_item2 &rhr)
{
Sales_item2 result(lhr);
result += rhr;//调用复合赋值操作符
return result;
}
3,关系操作符
(1)如果类定义了==,一般也应该定义!=,其中一个操作应该通过调用另一个操作来实现;
示例:
bool operator==(const Sales_item2 book1, const Sales_item2 book2)
{
//所有成员都相等,才相等
return (book1.isbn == book2.isbn) && //调用了string类的相等操作符
(book1.units_sold == book2.units_sold) &&
(book1.revenue == book2.revenue);
}
bool operator!=(const Sales_item2 book1, const Sales_item2 book2)
{
return !(book1 == book2);//注意这种用法
}
4,完整示例
/*******************************************************************/
// 重载算术与关系操作符(14.12)
/*******************************************************************/
// 类的定义
class Sales_item2 {
friend ostream& operator<<(ostream &os, const Sales_item2 &book);
friend Sales_item2 operator+ (const Sales_item2 &lhr, const Sales_item2 &rhr);
friend bool operator==(const Sales_item2 book1, const Sales_item2 book2);
friend bool operator!=(const Sales_item2 book1, const Sales_item2 book2);
public:
Sales_item2() : units_sold(0), revenue(0.0) { }
Sales_item2(const string &book) :isbn(book), units_sold(0), revenue(0.0) { }
Sales_item2(const string &book, unsigned new_sold, double new_revenue) :
isbn(book), units_sold(new_sold), revenue(new_revenue) { }
public:
// operations on Sales_item2 objects
// member binary operator: left-hand operand bound to implicit this pointer
Sales_item2& operator+=(const Sales_item2&);
private:
std::string isbn;
unsigned units_sold;//销售数量
double revenue;//收入
};
//成员函数与友元函数的定义
ostream & operator<<(ostream &os, const Sales_item2 &book)
{
os << book.isbn << "\t"
<< book.units_sold << "\t"
<< book.revenue;
return os;
}
// 复合赋值操作符,成员函数
Sales_item2& Sales_item2::operator+=(const Sales_item2& book)
{
this->units_sold += book.units_sold;
this->revenue += book.revenue;
return *this;
}
// 算术操作符,友员函数
Sales_item2 operator+ (const Sales_item2 &lhr, const Sales_item2 &rhr)
{
Sales_item2 result(lhr);
result += rhr;
return result;
}
bool operator==(const Sales_item2 book1, const Sales_item2 book2)
{
//所有成员都相等,才相等
return (book1.isbn == book2.isbn) && //调用了string类的相等操作符
(book1.units_sold == book2.units_sold) &&
(book1.revenue == book2.revenue);
}
bool operator!=(const Sales_item2 book1, const Sales_item2 book2)
{
return !(book1 == book2);//注意这种用法
}
//main函数
int main()
{
Sales_item2 book1("978-7-115-14554-3/TP", 4, 99.0 * 4);
Sales_item2 book2(book1);
cout << book1 + book2 << endl;
if (book1 == book2)
{
cout << "the same book!" << endl;
}
system("pause");
return 0;
}