chap 13:重载操作符与转换、重载函数的匹配(转)

来源:互联网 发布:python开发环境下载 编辑:程序博客网 时间:2024/06/08 20:08

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、如果重载中的两个函数可以用 同一转换函数 匹配,则使用在转换之后或之前的标准转换序列的等级来确定最佳匹配

[cpp] view plaincopyprint?
  1. struct SmallInt{  
  2.       <span style="color:#ff0000;">operator int(){return val;}</span>  
  3.       int val;  
  4. };  
  5. void computer(int);  
  6. void computer(double);  
  7. void computer(long double);  
  8.   
  9. SmallInt obj;  
  10. computer(obj);//ok; SmallInt只能转换成int,最佳匹配为computer(int)  

     如果可以使用不同” 转换操作“,编译器认为这两个匹配一样好,不管之前或之后的标准转换序列的等级如何,都会产生歧义

[cpp] view plaincopyprint?
  1. struct SmallInt{  
  2.       <span style="color:#ff0000;">operator int(){return val;}  
  3.       operator double(){return dval;}</span>  
  4.       int val;  
  5.       double dval;  
  6. };  
  7. void computer(int);  
  8. void computer(double);  
  9. void computer(long double);  
  10.   
  11. SmallInt obj;  
  12. computer(obj);//error ;因为SmallInt可以转换成int或double,所以存在不同的 转换操作 ,从而产生歧义; 

原创粉丝点击