运算符重载是为了能够更方便地操作类类型数据而设计的。与函数调用一样,运算符重载有自己的参数列表和返回值,重载前运算符是几目的,重载后仍是几目的,
不可更改。此外该运算符的优先级也不可更改。
重载的运算符参数中至少要有一个类类型或枚举类型,这样防止了该运算符对build-in数据类型运算的重定义。
四个不可重载的运算符
1. :: 2. .* 3. . 4. ?:
三个最好不重载的运算符
&& || ,
除了函数调用运算符 operator(),其余的运算符重载不可以有默认参数(default argument)
如果该重载的运算符是作为类成员的话,也含有隐含的this指针,绑定在第一个参数上。所以当重载运算符作为类成员时,可以少一个操作数。通常,我们将赋值运算符定义为类成员,算术运算符和逻辑运算符定义为非类成员的。
class myclass{
//.....
};
myclass& myclass::operator+=(const myclass&);
myclass operator+(const myclass&, const myclass&); |
注意以上两个函数参数及返回值的差别,符合赋值运算符定义为类成员,this指针绑定在左操作数上,返回一个该类型的引用。普通+运算符带双操作数,返回一个参数类型的游值。
如果某非成员重载的运算符需要访问类的私有成员,可将其声明为友元的。
隐式调用运算符重载,非类成员型的
显式的
cout<<operator+(OBJ1,OBJ2)<<endl; |
隐式调用运算符重载,类成员型的,以符合赋值运算符为例
显式的
运算符重载主要主义的地方:
1.不要对那些build-in类型参数进行重载
2.先想好类的接口(公有函数),再进行运算符重载设计
3.如果重载了双目的算术,移位运算符,最好也重载他们的单目符合版本。
4.如果重载了判等(==),最好也重载(!=)
5.是否作为类成员很重要。
赋值(=)、下标([])、调用(())和成员访问(->),必须作为类成员否则编译时会报错。
下标([]),要注意const与非const版本。
符合赋值(+=)这种可以修改自身的通常也作为类成员,但非类成员不会报错。返回通常是*this。
自增,自减,解除引用同上,通常作为类成员。后缀自增比前缀多一个int参数,实现时不使用,显示调用时传入0。
算术,逻辑,判等,位运算最好定义为非类成员。(想象一下作为参数的场景)
输入输出运算符,必须声明在类内,因为其第一参数为流类型,但通常声明为该类的友元,便于访问数据成员。输入要比输出注意异常控制,如输入尾,读取失败等。
阅读(1221) | 评论(0) | 转发(0) |