4.操作符重载:成员或非成员?
C++中,对操作符的重载有两种方法:将它作为成员函数或者不作为成员函数。如果我们正为一个不属于我们的类重载一个操作符,那它应该是一个非成员函数。
对于成员和非成员的选择会影响到使用该操作符的代码,比如,作为成员函数的操作符可以使用this指针,并可以用非限定形式来使用类中的成员。此外,这个选择结果还会影响到用户眼中该操作符的行为。如果操作符被实现为一个成员函数,那么我们就无法对第一个(最左边)操作符进行隐式类型转换。因此它也应该成为我们在成员和非成员之间进行选择的一个主要评判标准。
4.1一元操作符
如下面,有个类Vector,它创建自一个Direction对象和一个用double描述的数值:
class Direction
{
//...
};
class Vector
{
public:
Vector (const Direction&, double magnitude = 0.0);
};
由于Vector的构造函数中第二个参数有缺省值,我们就可以从一个Direction对象经过隐式转换得到一个vector对象。
如果我们希望为Vector重载一个一元操作符。如果我们把它定义为非成员函数,那么我们也就可以将它作用到Direction上去(因为Direction可以隐式地转换为Vector):
Vector operator-(const Vector&);
int main()
{
Direction d;
Vector v = -d;//合法的:operator-(Vector(d))
}
如果operator-是一个成员函数,那么隐式转换将被禁止,上面的编译就会出错,禁止隐式转换也是一件好事,会使得代码更易维护和被理解。
总结:
操作符 建议
所有一元操作符 成员
=、()、[]、-> 必须是成员
+=,-=,/=,*=,^=,&=,!=,%=,>>=,<<= 成员
所有其它的二元操作符 非成员
5.重载、缺省值以及省略符
省略符只应该用在类似于printf这样的需要无线个重载版本的函数中;使用缺省值可以让我们使用多种不同的方法来访问同一个函数;使用重载则适用于需要调用不同的函数这种场合之下。
如果重载、缺省值之间有一个是另一个的简化方式,并且同一个师兄可以用在这两种场合下,那么我们最好选择使用带缺省值的方式。比如有一个类String,它的构造函数带有一个const char*的参数,但是我们又希望它有一个缺省的构造函数,为了简便,我们可以使用一个带缺省值的参数:
class String
{
public:
String (const char* = "");
};
String s;//等同于“String s("");”
5.1缺省的指针和引用参数
当为指针参数或者引用提供缺省值时,小心一个小的语法陷阱
void f(const char*= "");
编译器会将*=当做一个单独的token来处理,这样就造成一个语法错误,我们应该在*=中间加个空格
void f(const char* = "");//引用同