为什么不要重载 && 和 || 操作符!!!
理论知识:
1)&&和 || 是C++中非常特殊的操作符
2)&&和 || 内置实现了短路规则
简单说明一下短路规则。
demo1
#include <iostream>
using namespace std;
int main()
{
<span style="white-space:pre"> </span>int a1 = 1;
<span style="white-space:pre"> </span>int a2 = 0;
<span style="white-space:pre"> </span>if (a1 || a2++) {
<span style="white-space:pre"> </span>cout << "||\n";
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if (a2 && a1++) {
<span style="white-space:pre"> </span>cout << "&&\n";
<span style="white-space:pre"> </span>} // 只输出了|| 。并没有输出&&
<span style="white-space:pre"> </span>cout << a1; // a1还是等于1;
<span style="white-space:pre"> </span>return 0;
}
第一个if的判断条件中因为a1是真,所以整个逻辑或就是真,不再执行a2++的部分,所以第二个if 语句的判断条件中a2为假,并且导致了整个逻辑与为假,不执行a1++的部分,所以最后的输出a1还是1。这就是内置的短路机制。
3)操作符重载是靠函数重载来完成的
4)操作数作为函数参数传递
5)C++的函数参数都会被求值,无法实现短路规则
demo2
#include <cstdlib>
#include <iostream>
using namespace std;
class Test
{
int i;
public:
Test(int i)
{
this->i = i;
}
Test operator+ (const Test& obj)
{
Test ret(0);
cout << "执行+号重载函数" << endl;
ret.i = i + obj.i;
return ret;
}
bool operator&& (const Test& obj)
{
cout << "执行&&重载函数" << endl;
return i && obj.i;
}
};
// && 从左向右
int main()
{
int a1 = 0;
int a2 = 1;
cout << "注意:&&操作符的结合顺序是从左向右" << endl;
if (a1 && (a1 + a2))
{
cout << "有一个是假,则不在执行下一个表达式的计算" << endl;
}
Test t1 = 0;
Test t2 = 1;
//if( t1 && (t1 + t2) )
//t1 && t1.operator+(t2)
// t1.operator&&( t1.operator+(t2) )
// && || 重载他们 不会产生短路效果
if ((t1 + t2) && t1)
{
//t1.operator+(t2) && t1;
//(t1.operator+(t2)).operator&&(t1);
cout << "两个函数都被执行了,而且是先执行了+" << endl;
}
return 0;
}
说明:比如考虑
(t1 + t2) && t1
成员函数的调用本质是
(t1.operator+(t2)).operator&&(t1);
这样的结果是不可能产生短路效果的。
同理:
t1 && (t1 + t2)
它的调用本质的是
t1.operator&&( t1.operator+(t2) )
所以我们重载 && 和 || 都不能实现短路效果,所以一般重载的时候我们都不对这两个运算符进行重载。
为什么不要重载 && 和 || 操作符!!!的更多相关文章
- C++ 之 重载赋值操作符
Widget 类中,定义了一个 Bitmap 类型的私有数据成员 -- pb 指针 class Bitmap { ... }; class Widget { private: Bitmap *pb; ...
- C++中复制构造函数与重载赋值操作符总结
前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义: 2.复制构造函数和重载赋值操作符的调用时机: 3.复制构造函数和重载赋值操作符 ...
- C++中复制构造函数与重载赋值操作符
我们都知道,在C++中建立一个类,这个类中肯定会包括构造函数.析构函数.复制构造函数和重载赋值操作:即使在你没有明确定义的情况下,编译器也会给你生成这样的四个函数.例如以下类: class CTe ...
- 5.9 C++重载转型操作符
参考:http://www.weixueyuan.net/view/6387.html 注意: 转型构造函数可以将其它类型的参数转换为类类型,如果我们要进行相反的转换过程,将类类型转换为其它数据类型, ...
- 5.6 C++重载下标操作符
参考:http://www.weixueyuan.net/view/6384.html 总结: 下标操作符是必须要以类的成员函数的形式进行重载的.其在类中的声明格式如下: 返回类型 & ...
- 5.5 C++重载赋值操作符
参考:http://www.weixueyuan.net/view/6383.html 总结: 重载赋值操作符同重载类的是拷贝构造函数的原因是一样,将一个对象拷贝给另一个对象,同时当类中存在指针类型的 ...
- 【c++】c++中重载输出操作符,为什么要返回引用
针对:ostream & operator <<(ostream & os, const ClassType &object) 说明几点: 1.第一个形参为对ost ...
- Effective C++(10) 重载赋值操作符时,返回该对象的引用(retrun *this)
问题聚焦: 这个准则比较简短,但是往往就是这种细节的地方,可以提高你的代码质量. 细节决定成败,让我们一起学习这条重载赋值操作符时需要遵守的准则吧. 还是以一个例子开始: Demo // 连锁赋值 x ...
- C++ 重载操作符- 02 重载输入输出操作符
重载输入输出操作符 本篇博客主要介绍两个操作符重载.一个是 <<(输出操作符).一个是 >> (输入操作符) 现在就使用实例来学习:如何重载输入和输出操作符. #include ...
- C++重载赋值操作符
1.C++中重载赋值操作函数应该返回什么? 类重载赋值操作符一般都是作为成员函数而存在的,那函数应该返回什么类型呢?参考内置类型的赋值操作,例如 int x,y,z; x=y=z=15; 赋值行为相当 ...
随机推荐
- 阿里 & 酷家乐:实习生面试
最近海投了十家公司,暂时有阿里两面(已凉).酷家乐两面(大概凉了).网易一面.前两个都是基础知识发挥得还可以,两家公司二面都凉凉. 阿里一面(3.21 26min) 刚好买了中饭回宿舍打开正准备吃的时 ...
- 深入理解final关键字
在了解了final关键字的基本用法之后,这一节我们来看一下final关键字容易混淆的地方. 1.类的final变量和普通变量有什么区别? 当用final作用于类的成员变量时,成员变量(注意是类的成员变 ...
- 文件操作(open\read\write\close)
为了方便演示,我们建立了一个示范文本,如下所示: hello,我是代码螺丝钉 test1 test2 test3 文件的读 f = open("示范文本","r" ...
- linux C 刚初始化后的一个变量在调用一个静态库中函数后被异常修改为乱码
linux C 中声明并初始化一个变量const char a[512]="test";后,接着调用了一个静态库中的函数函数test(b);,a并没有传入test函数,但在调用这个 ...
- python:浅析python 中__name__ = '__main__' 的作用(转载)
每次看文章的源码时,Python的主程序中都会看到开头有这个,查了一下作用:https://www.cnblogs.com/alan-babyblog/p/5147770.html. 讲的很详细,就直 ...
- 小白到大神,Python 密集知识点汇总
Python 基础 1. 变量 你可以把变量想象成一个用来存储值的单词.我们看个例子. Python 中定义一个变量并为它赋值是很容易的.假如你想存储数字 1 到变量 "one" ...
- PHP 5 String 函数
PHP 5 String 函数 PHP String 函数是 PHP 核心的组成部分.无需安装即可使用这些函数. 函数 描述 addcslashes() 返回在指定的字符前添加反斜杠的字符串. add ...
- Python File(文件) 方法
file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数: 序号 方法及描述 1 file.close() 关闭文件.关闭后文件不能再进行读写操作. 2 file.flush() ...
- JAVA生成数字0~9字母A~Z混合编码0000、0001...0009、000A...000Z、0010......
分别是求下一个编码 和 输出所有编码 /** * 用1--9加A--Z混合编码 使用ASCII码判断 * LYL * 传一个值 求下一个编码 */ public String getABCDCode( ...
- pycallgraph 追踪Python函数内部调用
安装 安装pycallgraph 安装依赖 使用 待测脚本 追踪脚本 追踪结果 高级篇 隐藏私密函数 控制最大追踪深度 总结 GitHub上好代码真的是太多了,名副其实的一个宝藏.但是最近自己也反思了 ...