C++ Super-FAQ 『Operator Overloading』

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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内容已经发生改变。

以上是关于C++ Super-FAQ 『Operator Overloading』的主要内容,如果未能解决你的问题,请参考以下文章

C++ Super-FAQ 『Constructor』

C++ Super-FAQ 『Classes and Objects』

“operator !=”是不是应该在 C++ 中始终通过“operator ==”来实现?

C++中operator用法

C++,关于operator的详细总解,(原理和用法)

c++ new operator和operator new,delete operator和operator delete