当前位置:编程学习 > C/C++ >>

避免重载&&(逻辑与)、||(逻辑或)或,(逗号)操作符

这几天读《C++编程规范http://book.douban.com/subject/1459007/》读到第30条:“避免重载&&、||或,(逗号)”,一直不能完全吃透。今天才理解,原来是这么回事:
 
  内建的&&(逻辑与)、||(逻辑或)和,(逗号)操作符总是满足以下性质:
从左至右对操作数进行求值;
对于&&操作符,若左操作数为假,那么右操作数将不会求值,所以我们可以放心地写下
[cpp]
if (p && p->next) 
这样的代码而不用担心p为0时p->next会先被求值;
类似地,对于||操作符,若左操作数为真,那么右操作数将不会被求值。
 
  上面第2点和第3点又叫做“短路求值法(Short Circut Evaluation)”。
 
  如果我们重载了这三个运算符,会发生什么呢?事实上,当一个操作符被重载时,编译器就会将该操作符视为一个函数,而不是一个真正的操作符。一个函数的参数总是会被全部求值,而且其求值顺序是未定义的。因此上述三个性质就全都不能满足了!
 
  考虑下面这个程序:
 
[cpp]
#include <iostream> 
#include <string> 
 
using namespace std; 
 
string retString() 

    cout << "string" << endl; 
    return "hello"; 

 
int retInt() 

    cout << "int" << endl; 
    return 47; 

 
int main() 

    retInt(), retString(); 

 
  不管用什么编译器,只要其支持C++标准,程序的输出都应该为
 
int
string
 
  但如果重载了逗号操作符,像下面这样:
[cpp]
void operator , (int a, const string &b) 


 
  用VS2010编译后,程序就会先输出string,再输出int,可见操作数是从右向左求值的。
 
  而如果对重载定义做少许的改动:
 
[cpp]
void operator , (const int &a, const string &b) 


 
  也就是把左操作数a的定义变成常量引用。那么程序又会先输出int再输出string了。你可能会怀疑此时程序调用的是内建逗号操作符,那么可以在重载定义中加一条cout输出语句,就知道调用的其实还是重载操作符。只不过把参数的定义改了改,参数的求值顺序就变了,是不是很“神奇”?



摘自 子子翔的专栏
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,