避免重载&&(逻辑与)、||(逻辑或)或,(逗号)操作符
来源:互联网 发布:曦力音视频剪辑软件 编辑:程序博客网 时间:2024/05/18 15:28
这几天读《C++编程规范》读到第30条:“避免重载&&、||或,(逗号)”,一直不能完全吃透。今天才理解,原来是这么回事:
内建的&&(逻辑与)、||(逻辑或)和,(逗号)操作符总是满足以下性质:
- 从左至右对操作数进行求值;
- 对于&&操作符,若左操作数为假,那么右操作数将不会求值,所以我们可以放心地写下
if (p && p->next)
这样的代码而不用担心p为0时p->next会先被求值; - 类似地,对于||操作符,若左操作数为真,那么右操作数将不会被求值。
上面第2点和第3点又叫做“短路求值法(Short Circut Evaluation)”。
如果我们重载了这三个运算符,会发生什么呢?事实上,当一个操作符被重载时,编译器就会将该操作符视为一个函数,而不是一个真正的操作符。一个函数的参数总是会被全部求值,而且其求值顺序是未定义的。因此上述三个性质就全都不能满足了!
考虑下面这个程序:
#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
但如果重载了逗号操作符,像下面这样:
void operator , (int a, const string &b){}
用VS2010编译后,程序就会先输出string,再输出int,可见操作数是从右向左求值的。
而如果对重载定义做少许的改动:
void operator , (const int &a, const string &b){}
也就是把左操作数a的定义变成常量引用。那么程序又会先输出int再输出string了。你可能会怀疑此时程序调用的是内建逗号操作符,那么可以在重载定义中加一条cout输出语句,就知道调用的其实还是重载操作符。只不过把参数的定义改了改,参数的求值顺序就变了,是不是很“神奇”?
- 避免重载&&(逻辑与)、||(逻辑或)或,(逗号)操作符
- 小括号'()'运算符重载、逻辑与'&&'、逻辑或'||'运算符重载说明(需要了解)
- 逻辑与、逻辑或 重载
- 布尔操作符:逻辑或 (||)、逻辑与(&&)、逻辑非(!)
- javascript-逻辑与(&&)逻辑或(||)
- 逻辑运算(逻辑非,逻辑与,逻辑或,逻辑异或)
- C++编程规范之30:避免重载&&,||或,(逗号)
- 逻辑与和逻辑或的重载
- 逻辑与和逻辑或运算符重载
- 括号,逻辑与,逻辑或--运算符重载
- C++学习笔记:为什么不要重载逻辑与和逻辑或&& || 操作符
- 逻辑或操作符
- js中的逻辑或(||)操作
- js中的逻辑与(&&)和逻辑或(||)
- [转]js中的逻辑与(&&)和逻辑或(||)
- js中的逻辑与(&&)和逻辑或(||)问题
- js中的逻辑与(&&)和逻辑或(||)
- js中的逻辑与(&&)和逻辑或(||)
- 几种过滤html代码的方法总结
- 借“技术文章如何写作才能有较好的阅读体验”,说我们要认真的对待博客和技术.
- android 版本更改
- 黑马程序员---$.getScript()方法和$.getJson()方法、$.ajax()
- VB程序----两位数乘法
- 避免重载&&(逻辑与)、||(逻辑或)或,(逗号)操作符
- Entity Framework: duplicate rows in resultset from a view
- poj 2288 Islands and Bridges
- plsql学习:cursor游标使用例子(1)
- 腾讯微博发布一条微博——(非SDK版)(原创)
- Server.HTMLEncode用法
- 在Ubuntu上下载、编译和安装Android最新源代码
- Java应用技巧:Cookie 的操作详解
- “图片差异检查”辅助工具(即“大家来找茬”辅助工具)源码分享