C++ 运算符重载

来源:互联网 发布:二叉树层次打印 java 编辑:程序博客网 时间:2024/06/18 04:33

C++运算符重载函数可以是类的成员函数也可以是全局函数。

对于-> ,[ ]和()以及赋值运算符必须重载为类的成员函数。

对于二元运算符来说,如果左操作数不是该类的对象的话,那么该运算符重载函数不能作为类的成员函数,比如流插入运算符<<和流提取运算符>> ,它们必须作为全局函数。

当运算符函数是类的成员函数时,该运算符的左操作数必须是该类的对象。若左操作数是不同类的对象或者基本类型对象,那么该运算符函数必须作为全局函数来实现。如果该运算符函数会访问类的private或者protected成员,那么请把它设为该类的友元函数。


重载的++运算符:

①前置++

一个类的前置++运算符应该返回该类对象的一个引用,以便返回的值可以作为左值继续对其赋值。

类& operator++();

②后置++

后置++运算符应该返回该类的对象,因为在进行自增前,后置操作先返回一个包含对象原始值的临时对象,临时对象只能作为右值,不能作为左值出现在赋值运算符=的左侧。

为了让编译器区分出前置++与后置++,后置++的函数原型如下:

类 operator++(int a);

调用的时候编译器自动会调用operator++(0),int a纯粹是个哑值,没任何作用,只是为了让编译器区分前置++与后置++。


重载的->运算符:

箭头操作符接受一个对象和其成员名,看起来它就像个二元操作符。但是不管外表看起来如何,箭头操作符不接受显式形参。

没有第二个形参是因为->的右操作数是类成员的一个标识符,没有明显可行的途径将一个标识符作为形参传递给函数。

定义两个类如下:

class Element{public:  action();private:  int val;};class Test{public:    Element* operator->()    {return &data;}private:    Element data;};

Element* a;a->action();Test t;t->action();

由于优先级的原因,实际上等价于

(a->action)();
即编译器先对a->action求值,求值完后再调用求值结果。

编译器对a->action进行求值:如果

(1) a是指向含有action成员的类的对象的一个指针,那么编译器将该代码编译为调用该对象的action成员;

(2) a是定义了operator->()操作符的类的一个对象,则a->action就被编译成(a.operator->())->action。即执行a的operator->()函数,设执行后返回的结果为result,那么该语句就变成了result->action,则编译器继续编译result->action,重复进行上述过程的判断...

(3) 除上述两种情况外,其他情况都会报错。


operator->()函数的返回类型:

要么返回指向类类型的指针,要么就返回包含箭头操作符重载函数的类的对象或其引用。

对于后一种情况,将递归应用该操作符,即编译器将检查返回的对象所属的类中是否包含了operator->()函数,如果有,则就继续调用该operator->()函数。这个过程会一直进行下去,直至返回一个含有->右端指定成员的类对象的指针。


0 0
原创粉丝点击