1、重载操作符必须至少有一个类类型操作数。作为类成员的重载函数,其形参看起来比操作数数目少1;作为成员函数的操作符有一个隐含的this形参,限定为第一个操作数。
2、不能重载的操作符有: 条件操作符(?:)、指向类成员操作的指针( .*)、作用域解析操作符(::)
3、不应该重载的操作符: 取址操作符(&)、逗号操作符(,)、逻辑与操作符(&&)、逻辑或操作符(||)
4、对于任意二元操作符@,aa@bb被解析为:aa.operator@(bb)或operator@(aa,bb);对任意一元操作符@,@aa被解析为:aa.operator@()或operator@(aa)
重载操作符通常要考虑的两个问题,是否作为成员函数,返回类型;下面逐个说明:
5、必须作为非静态成员函数的操作符: 赋值(=)、下标([ ])、调用(( ))、成员访问箭头(->)、转换操作符
6、通常作为非静态成员函数的操作符:符合赋值、自增、自减
7、必须作为非成员函数的操作符:输入输出操作符(<< 和>>)
8、通常作为非成员函数的操作符:对称的操作符(比如:算术操作符,==,关系操作符,位操作符);通常把非成员函数的操作符设置为所操作类的”友元“
9、赋值操作符的重载注意:作为成员函数;返回reference to *this;处理”自我赋值“,使用语句 if(*this == &rhs);
10、下标操作符的重载注意:作为成员函数;返回引用(因为下标操作符是左值);定义两个版本(const成员和非const成员)
11、成员访问操作符(->和*)的重载注意:作为成员函数,不接受显示形参;operator->的返回类型必须是 指向类类型的指针 或 定义了自己的箭头操作符的类类型对象;比如:代码: point -> action(); //如果point是一个指针,指向具有名为action的成员的对象,改代码的作用是调用该对象的action成员;否则,如果point定义了自己的operator->,则执行point的operator->()
12、调用操作符的重载注意:即operator();定义了调用操作符的类称为函数对象(function object)
13、转换操作符(conversion operator):通用形式为operator type();必须是成员函数;不能指定返回类型;不显示接受形参;转换操作符引起类类型的转换;
重载函数的匹配:
1、可行函数:函数的形参个数与调用的实参个数相同(默认实参例外),且每一个实参的类型必须与对应形参的类型匹配 或者 可被隐身转换为对应的形参类型;
2、含有一个形参的重载函数的匹配,根据转换等级类确定;
含有多个形参的匹配,匹配成功应该满足下列条件:(1)其每个形参的匹配都不劣于其他可行函数提供的匹配;(2)至少有一个实参的匹配优于其他可行函数提供的匹配;如果不满足这两个条件,就会出错(出错的可能性之一是二义性);
3、为了确定最佳匹配,编译器将实参类型到相应形参类型的转换划分等级;转换等级以降序排列如下:
(1)精确匹配(exact match): 实参与形参类型相同;
(2)通过类型提升(promotion):比如:所以比int小的类型提升到int;
(3)通过标准转换(standard conversion):使用static_cast/const_cast/reinterpret_cast或者C语言风格的强制转换;
(4)t通过类类型转换(class-type conversion):构造函数/转换操作符
4、重载和const形参:只有形参是引用或指针时,形参是否为const才有影响;可基于函数的引用/指针形参是指向const对象还是指向非const对象来实现重载;const实参只能匹配const形参,非const实参既可以匹配非const实参 也可以匹配const实参,但非const实参是精确的匹配;
5、如果重载中的两个函数可以用 同一转换函数 匹配,则使用在转换之后或之前的标准转换序列的等级来确定最佳匹配
- struct SmallInt{
- <span style="color:#ff0000;">operator int(){return val;}</span>
- int val;
- };
- void computer(int);
- void computer(double);
- void computer(long double);
- SmallInt obj;
- computer(obj);//ok; SmallInt只能转换成int,最佳匹配为computer(int)
如果可以使用不同” 转换操作“,编译器认为这两个匹配一样好,不管之前或之后的标准转换序列的等级如何,都会产生歧义
- struct SmallInt{
- <span style="color:#ff0000;">operator int(){return val;}
- operator double(){return dval;}</span>
- int val;
- double dval;
- };
- void computer(int);
- void computer(double);
- void computer(long double);
- SmallInt obj;
- computer(obj);//error ;因为SmallInt可以转换成int或double,所以存在不同的 转换操作 ,从而产生歧义;