《More Effective C++》《操作符——7、千万不要重载&&,||和,操作符》

本文探讨了C++中重载逻辑操作符&&和||时遇到的问题,尤其是它们在函数调用中的行为变化,导致短路求值特性丧失。同时指出了逗号操作符的重载也受到参数评估顺序不确定性的限制。
摘要由CSDN通过智能技术生成

1、Terms7:千万不要重载&&,||和,操作符

1.1、重载&&,|| 运算符

C/C++语言对于逻辑表达式具有 “逻辑短路” 的性质,即一旦确定了真假值,表达式中即使有尚未检查的部分,都将返回。
内置的&&和||操作符有"短路求值"的特性。对于&&如果第一个操作数为假,那么&&即返回为真,不再对第二个操作数进行求值,||一旦第一个操作数为真,不再对后面操作数求值,利用这个特性可以写出下面的代码:

char *p;
if ((p != NULL) && printf("%c", *p)) ...                     //(1)
    
int rangeCheck(int index)
{
    if ((index < lowerBound) || (index > upperBound)) ...    //(2)
    ...
}

(1)中你不用担心p为NULL时,调用printf函数会出现错误,因为一旦p为NULL逻辑与的检测将返回FASLE,无需计算后面的部分。
(2)中检查下标值是否越界,你也不用担心如果index已经越下界还会与上界进行比较,因为前者正确之后即返回TRUE,无需计算后者。
2、当重载&&和||时,也希望具有上面的性质。但事与愿违,多数情况是无法达到这种要求。如将operator &&重载,当我们写出如下的表达式:

if (expression1 && expresssion2)    ...
 
//编译器会视作:
 
if (expression1.operator&&(expression2))   ...          //operator&& 是member-function
 
//或者
 
if (operator&&(expression1, expression2))  ...          //operator&& 是global-function

当函数调用动作被执行,所有参数值都必须被评估;函数调用动作中各参数的评估顺序不确定。
上面两种形式,都会将计算expression1和expression2的值,而且计算的顺序也不确定,这样就违背了之前谈论的“逻辑短路”现象。
故,一旦进行重载,&&和||的左右操作数就是两个无分前后的参数而已,也就是说短路求值的特性没有了。当函数被调用时,所有参数都被求值并传入,而C++没有规定个参数的求职顺序,之前的代码就不能用了。

1.2 重载 , 运算符

逗号(,)操作符的含义,是从左到右依次计算每个表达式的值,最后返回的是最后一个表达式的值,如

expression1, expression2, ..., expressionN;

将依次计算expression1,expression2,…的值,最后返回值为expressionN的值
重载逗号(,)操作符,如果是以global-function形式给出,我们无法确保参数的计算顺序是从左到右的(因为两个表达式都被当做函数调用时的自变量,传递给该操作符函数,而你无法控制一个函数的自变量的评估顺序);如果以member-function形式给出,仍不能保证逗号操作符的左操作数先被计算(因为编译器不强迫做这样的事情)。因此,不能确保完成逗号操作符所期望的功能。

1.3 哪些能重载,哪些不能重载

C++语言中不能重载的操作符有:

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

可以重载的操作符有:

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

2、总结

书山有路勤为径,学海无涯苦作舟。

3、参考

3.1《More Effective C++》

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值