您的位置:首页 > 编程语言 > C语言/C++

C++ Super-FAQ 『Operator Overloading』

2016-03-01 11:39 423 查看
哪些操作符不能被重载

. ?: :: .* 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),专家们的意见无法统一。

操作符重载原则

按照日常使用习惯重载,便于用户使用;

数学运算操作符应符合运算原理;

数学运算操作符必须具有实际意义时才能提供;

混合类型数学运算符也必须具有实际意义时才能提供;

若定义constructive operators,最好通过值返回;

若定义constructive operators,最好不要修改操作数;

若定义constructive operators,最好允许做操作数的类型提升;

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.

若自定义x++,++x和x+=操作符,必须使其符合一般规则;

若定义pointer-like objects,*p, p[i], *(p+i)必须符合一般使用规则;

下标操作符一般需要成对出现(const和非const版本);

若定义x==y,有且只有这两个对象behaviorally equivalent时返回true;

若定义大小比较操作符,则间接比较与直接比较结果应保持一致;

避免会误导使用者的操作符重载。

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内容已经发生改变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: