C++重载运算符
运算符重载的两种方式
对于很多运算符来说,可以选择使用成员函数或非成员函数来实现运算符重载。一般来说非成员函数应该是友元函数,这样才能直接访问类的私有数据。例如,Time类的加法运算符在Time类声明中的原型为:
Time operator+(const Time &t) const; //member version
这个成员函数的声明方式。
这个函数的声明也可以使用友元函数的方式:
friend Time operator+(const Time &t1, const Time &t2) //nonmember version
加法运算需要两个操作数,对于成员函数版本,一个操作数通过this指针隐式地传递,另一个操作数作为函数参数显式的传递;对于友元函数的版本来说,两个操作数都作为参数来传递。
这两个原型都与表达式T2 + T3匹配,其中T2和T3都是Time类型对象。也就是说,编译器将下面的语句:
T1 = T2 + T3; 转换为下面的任何一个: T1 = T2.operator+(T3); //member function T1 = operator+(T2, T3); //nonmember function
记住,在选择运算符时,必须选择其中的一种格式,不能同时选择两种格式。因为这两种格式都与同一个表达式匹配,同时定义这两种格式将被视为二义性错误,导致编译错误。
那么哪一种格式最好呢?对于某些运算符来说,成员函数是唯一合法的选择,比如说自增的operator++运算,operator=运算。在其他情况下,这两种格式并没有太大的区别。
运算符重载的返回类型
重载运算符的返回值无非就两种:返回对象和返回对象的引用。
想operator+这样的运算符,两个操作数相加然后赋值给另外一个对象,这种的要返回一个新的对象,不能返回一个对象的引用,至于原因看条款21。返回一个对象也能够兼容a+b+c这样的语句。
但是对于operator=这样的运算符,只能用成员函数写,要返回一个对象的引用的,其实不返回任何东西也是可以的,返回对象的引用,为的就是兼容a=b=c这样的操作。为什么不返回一个const的对象的引用呢?为了兼容(a=b)=c这样的操作。