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

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[]
+ - * / % ^ & | ~ ! = < > += -= *= /= %=
^= &= |= << >> >>= == != <= >= && ||
++ – , ->* -> () []

而只因为可以重载这些操作符,就毫无理由地去进行,是没有道理的。
如果你没有什么好理由将某个操作符重载,就不要去做。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值