在《运算符重载(一)》我们介绍了运算符重载的基本概念,以及基本形式。那么再运算符重载中,参数的传递有什么遵循的原则?返回值的类型又遵循什么原则呢?这些问题都 在这一篇文章中回答。
(1)运算符重载函数中的参数个数应该有几个
运算符重载函数的参数个数取决于两个因素。一是运算符是一元运算符还是二元运算符,二是采用友元函数重载还是采用成员函数重载
如果是一元运算符,采用友元函数重载就要有一个参数,采用成员函数重载,就不需要参数(因为成员函数隐式的传递了this指针)
1 class Integer{ 2 int i; 3 public: 4 };
1 friend const Integer& operator++(Integer& a);//前置++,一元运算符,采用的是友元函数重载
1 const Integer& operator++();//前置++,一元运算符,采用的是成员函数重载
如果是二元运算符,采用友元函数重载需要两个参数,采用成员函数重载,需要一个参数(因为成员函数隐式的传递了this指针)。这里就不再举例子了
(2)重载运算符函数参数的类型应该怎么选择
首先由于参数传递时,如果采用按值传递,那么就会生成临时对象,调用拷贝构造函数等,会严重影响程序的效率,所以一般采用引用的形式。如果传递的参数需要在函数中被修改,不能用const引用,如果在函数中没有修改参数,那么就传递const 引用。
(3)返回值的类型应该是引用还是应该是值类型
返回值类型根据返回的是否为新产生的对象(因为是在运算符重载函数中产生的,所以产生的新对象时一个局部对象,我们知道当函数的返回值类型是引用时,是不能返回局部变量的,因为函数调用完,局部变量就释放了),还是原来传递给函数的对象。如果是新产生的对象,则返回值类型为值类型。如果返回的值为原来参数传递给函数的,则返回值类型为引用
#ifndef INTEGER_H #define INTEGER_H #include<iostream> class Integer { long i; public: Integer(int ll = 0) :i(ll){} ~Integer(){} //operators that create new ,modified value:运算符创建新的对象,并修改了值
//+ - * / % ^ | & >> <<,这些运算符是二元运算符,运算符的两个参数在函数中都没有被改变,所以都是以const 引用的形式传递的
//这些函数在是实现都是生成了另外一个新的Integer对象,并且返回这个新对象,例如+号运算符重载的实现是,return Integer(left.i+right.i);所以函数返回值是const Integer 而不是const Integer&。
//至于返回值是否加const,那就需要根据情况判定了,返回值需要调用非const函数,那么就不能加const。不需要就可以加const friend const Integer operator+(const Integer& left, const Integer& right); friend const Integer operator-(const Integer& left, const Integer& right); friend const Integer operator*(const Integer& left, const Integer& right); friend const Integer operator/(const Integer& left, const Integer& right); friend const Integer operator%(const Integer& left, const Integer& right); friend const Integer operator^(const Integer& left, const Integer& right); friend const Integer operator|(const Integer& left, const Integer& right); friend const Integer operator&(const Integer& left, const Integer& right); friend const Integer operator>>(const Integer& left, const Integer& right); friend const Integer operator<<(const Integer& left, const Integer& right); //Assignments modify & return lvalue 赋值运算符,并返回左值
//下面这些运算符都是改变了运算符左边的操作数,右边的操作数没有被改变,所以第一个参数是非const的引用,右边的参数是const引用
//这些函数在是实现都是没有在函数内生成新对象,返回的值也是函数传递进入的引用,例如+=运算符重载的实现是,left.i+=right.i; return left;所以函数返回值是const Integer& 而不是const Integer。
//至于返回值是否加const,那就需要根据情况判定了,返回值需要调用非const函数,那么就不能加const。不需要就可以加const
friend Integer& operator+=(Integer& left,const Integer& right); friend Integer& operator-=(Integer& left, const Integer& right); friend Integer& operator*=(Integer& left, const Integer& right); friend Integer& operator/=(Integer& left, const Integer& right); friend Integer& operator%=(Integer& left, const Integer& right); friend Integer& operator^=(Integer& left, const Integer& right); friend Integer& operator&=(Integer& left, const Integer& right); friend Integer& operator|=(Integer& left, const Integer& right); friend Integer& operator>>=(Integer& left, const Integer& right); friend Integer& operator<<=(Integer& left, const Integer& right); //conditional operator return true/false
//
friend int operator==(const Integer& left,const Integer& right); friend int operator!=(const Integer& left, const Integer& right); friend int operator<(const Integer& left, const Integer& right); friend int operator<=(const Integer& left, const Integer& right); friend int operator>(const Integer& left, const Integer& right); friend int operator>=(const Integer& left, const Integer& right); friend int operator&&(const Integer& left, const Integer& right); friend int operator||(const Integer& left, const Integer& right); //write the contents to an ostream void print(std::ostream& os)const { os << i; }//这边要特别注意是,print函数是const成员函数,只能const对象调用 }; #endif //INTEGER_Hd