您的位置:首页 > 其它

条款7:千万不要重载&&,||和,操作符

2016-12-06 23:10 260 查看
C++对于“真假值表达式”采用所谓的“骤死式”评估方式。意思是一旦该表达式的真假值确定,即使表达式中还有部分尚未检验,整个评估工作仍告结束。

如果在global scope或是在每个class内对operator&&和operator||两函数进行重载工作,那么“函数调用 语义”会取代“骤死式 语义”。

也就是说,下面这个式子:

if(expression1 && expression2) ...


会被编译器视为以下两者之一:

if(expression1.operator&&(expression2)) ...
//假设operator&&是个member function


if(operator&&(expression1,expression2)) ...
//假设operator&&是个全局函数


这将产生重大的区别:

1.当函数调用动作被执行,所有参数值都必须评估完成,所以当我们调用operator&&和operator||时,两个参数都已评估完成。换句话说没有什么骤死式语义。

2.C++语言规范并未明确定义函数调用动作中各参数的评估顺序,所以没办法知道expression1和expression2哪个会先被评估。

所以,如果你将&&和||重载,就没有办法提供程序员预期的某种行为模式。所以请不要重载&&或||。

C++同样也有一些规则来定义逗号操作符(,)面对内建类型的行为。表达式中如果内含逗号,那么逗号左侧会先被评估,然后逗号的右侧再被评估;最后,整个逗号表达式的结果以逗号右侧的值为代表。

如果把操作符写成一个non-member function,你绝对无法保证左侧表达式一定比右侧表达式更早被评估,因为两个表达式都被当做函数调用时的自变量,传递给该操作符函数,而你无法控制一个函数的自变量评估顺序。

而将操作符写成一个member function,你仍然不能保证逗号操作符的左操作数会先被评估,因为编译器并不强迫做这样的事情。所以不要轻率地将它重载。

你不能重载以下操作符:

.      .*      ::      ?:
new    delete  sizeof  typeid
static_cast    dynamic_cast    const_cast  reinterpret_cast


你可以重载的操作符有:

operator new operator delete

operator new[] operator delete[]

+ - * / % ^ & | ~ ! = < > += -= *= /= %=

^= &= |= << >> >>= == != <= >= && ||

++ – , ->* -> () []

而只因为可以重载这些操作符,就毫无理由地去进行,是没有道理的。

如果你没有什么好理由将某个操作符重载,就不要去做。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: