第二章,操作符

条款7 千万不要重载&&(与)||(或), 逗号操作符

描述

C++允许和禁止重载的操作符如下:

//可重载:
operator new
operator delete
operator new []
operator delete []
+ - * / %
^ & | ~ ! = < >
+= -= *= /= %= ^= &= |=
<< >> >>= <<=
== != <= >= && || ++ -- ,
->* -> () []

//禁止重载:
. .* :: ?:
new delete sizeof typeid
static_cast dynamic_cast const_cast reinterpret_cast

尽管允许重载大部分操作符,但是不应该重载&&(与)ll(或), 逗号操作符,因为无法确保重载后的效果符合原来的大众所熟知的规则,会增加维护难度以及带来不必要的麻烦!

不能重载&&(与)||(或)操作符的原因

char *p;
...
if((p != 0) && (strlen(p) > 10))...

int reangeCheck(int index)
{
if((index < lowerBound) || (index > upperBound)) ...
}

与C一样,C++对于真假表达式的判断特点是,对于&&(与)若第一个判断是false,那么后面的表达式就不会进行判断,直接返回false;而对于||(或),一旦第一个表达式为true,后面的表达式也不会进行判断了;这是大部分C/C++开发者熟知的特点! 然而要重载这两个操作符的时候,会发现是无法实现这种特点的,这必然导致歧义的出现,也因此会对使用的开发者带来不少麻烦。

不能重载,(逗号)操作符的原因

for(int i = 0,j=10; i<=100; ++i,--j) //这里便使用到了逗号操作符(够冷门的,谁没事重载这玩意儿🐶)
{
...
}

这里的逗号操作符的逻辑是,编译器首先评估++i,然后是–j,而整个逗号表达式的返回结果是–j的返回值。由于无法保证左侧表达式一定先于右侧的更早被评估,所以是无法重载模仿实现这种效果的。这就是不建议重载逗号的原因。(一旦重载,你就改变了游戏规则,接手代码的人会携带大众规则被迫阅读你的私人定制规则,这很不友好,也不专业!)