C++ Super-FAQ 『Operator Overloading』

本文详细介绍了操作符重载的基本概念、限制条件、原则和应用实例,包括为何某些操作符不能被重载、如何定义操作符、矩阵类下标操作符的重载方式、前缀与后缀操作符的重载技巧以及具体示例。
  • 哪些操作符不能被重载
.     ?:     ::     .*     sizeof
由于一些历史原因,?:不能被重载。若重载expr1 ? expr2 : expr3,不能确保expr2或expr3中只有一个被执行。
sizeof是内嵌操作符,某些操作符依赖它的实现,故不允许重载。
域描述符::两边不是对象或表达式,而是供编译器识别的名称。 ::  performs a (compile time) scope resolution rather than an expression evaluation.
 
  • 程序员能自行定义操作符吗?
不能。
这并不是一个语言技术上的难题,而是重载后表达式的内容使用者无法统一意见,这容易导致严重的问题。
eg:
**表示指数操作,对于a**b**c表示(a**b)**c还是a**(b**c),专家们的意见无法统一。
 
  • 操作符重载原则
  1. 按照日常使用习惯重载,便于用户使用;
  2. 数学运算操作符应符合运算原理;
  3. 数学运算操作符必须具有实际意义时才能提供;
  4. 混合类型数学运算符也必须具有实际意义时才能提供;
  5. 若定义constructive operators,最好通过值返回;
  6. 若定义constructive operators,最好不要修改操作数;
  7. 若定义constructive operators,最好允许做操作数的类型提升;
  8. In general, your operator should change its operand(s) if and only if the operands get changed when you apply the same operator to intrinsic types.
  9. 若自定义x++,++x和x+=操作符,必须使其符合一般规则;
  10. 若定义pointer-like objects,*p, p[i], *(p+i)必须符合一般使用规则;
  11. 下标操作符一般需要成对出现(const和非const版本);
  12. 若定义x==y,有且只有这两个对象behaviorally equivalent时返回true;
  13. 若定义大小比较操作符,则间接比较与直接比较结果应保持一致;
  14. 避免会误导使用者的操作符重载。
 
constructive operators指那些计算后能构造新对象的操作符。
 
x++  and  ++x  should have the same observable effect on  x , and should differ only in what they return.  ++x  should return  x  by reference;  x++  should either return a copy (by value) of the original state of  x  or should have a  void  return-type.
 
  • 矩阵类的下标操作(subscript operator)符如何重载
使用operator()而不是operator[]。因为后者只能接收一个参数,而前者可以接收任意数量的参数。
double& operator() (unsigned row, unsigned col);        // Subscript operators often come in pairs
double  operator() (unsigned row, unsigned col) const;  // Subscript operators often come in pairs
 
对于二维矩阵使用operator[]访问,实际上是通过Operator[]返回一个对象数组的引用,然后再通过operator[]返回二维矩阵元素对象。
The array-of-array solution obviously works, but it is less flexible than  the operator() approach . Specifically, there are easy performance tuning tricks that can be done with the  operator()  approach that are more difficult in the  [][]  approach, and therefore the  [][]  approach is more likely to lead to bad performance, at least in some cases.
 
the  operator()  approach is never worse than, and sometimes better than, the  [][]  approach.
 
  m(i,j)  gives you a clean, simple way to check all the parameters and to hide (and therefore, if you want to, change) the internal data structure.
 
  • 如何重载前缀、后缀操作符
通过一个隐藏的参数。
class Number {
public:
  Number& operator++ ();    // prefix ++
  Number  operator++ (int); // postfix ++
};
 
注意:前缀版本返回引用;后缀版本返回值(或void)。因为后缀版本赋值内容是修改前的值,而此时this内容已经发生改变。

转载于:https://www.cnblogs.com/yanxingyoudao/p/5230374.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值