逻辑操作符的陷阱(三十二)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逻辑操作符的陷阱(三十二)相关的知识,希望对你有一定的参考价值。
我们今天来看看逻辑操作符,它的原生语义是:操作数只有两种值(true 和 false),逻辑表达式不用完全计算就能确定最终值,其最终结果只能是 true 或者 false。
下来我们来看个编程实验
#include <iostream> #include <string> using namespace std; int func(int i) { cout << "int func(int i): i = " << i << endl; return i; } int main() { if( func(0) && func(1) ) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } cout << endl; if( func(0) || func(1) ) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } return 0; }
我们利用在 C 语言中所学的知识,轻易可知第一个输出 false,第二个输出 true。并且第一个只打印出 func(0),第二个两个都会打印出。我们来看看编译结果
结果是这样的,那么这块是否没有什么可讲的吗?逻辑操作符可以重载吗?重载逻辑 操作符有什么意义?我们看个示例代码
#include <iostream> #include <string> using namespace std; class Test { int mValue; public: Test(int v) { mValue = v; } int value() const { return mValue; } }; bool operator && (const Test& r, const Test& l) { return r.value() && l.value(); } bool operator || (const Test& r, const Test& l) { return r.value() || l.value(); } Test func(Test i) { cout << "Test func(Test i) : i.value() = " << i.value() << endl; return i; } int main() { Test t0(0); Test t1(1); if( func(t0) && func(t1) ) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } cout << endl; if( func(1) || func(0) ) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } return 0; }
我们看到重载了逻辑操作符,在 func 函数中传入的是 Test 对象,然后看看编译结果是否和之前的一样呢?
我们看到虽然最后的结果是一样的,但是调用 func 函数和之前不同了。两次两个都调用了,这是怎么回事呢?我们回到操作符重载的本质来看,它是函数重载,我们试着写下它的原型,如下
#include <iostream> #include <string> using namespace std; class Test { int mValue; public: Test(int v) { mValue = v; } int value() const { return mValue; } }; bool operator && (const Test& r, const Test& l) { return r.value() && l.value(); } bool operator || (const Test& r, const Test& l) { return r.value() || l.value(); } Test func(Test i) { cout << "Test func(Test i) : i.value() = " << i.value() << endl; return i; } int main() { Test t0(0); Test t1(1); if( operator && (func(t0), func(t1)) ) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } cout << endl; if( operator || (func(1), func(0)) ) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } return 0; }
我们看到在第 43 和 54 行写成这样的形式,再次编译看看
结果和之前的是一样的,这便证明了操作符重载的本质是函数重载。C++ 通过函数调用扩展操作符的功能,进入函数体前必须完成所有参数的计算。函数参数的计算次序是不定的,短路法则则完全失效。因此,逻辑操作符重载后无法完全实现原生的语义。
我们通常在实际工程开发中避免重载逻辑操作符,通过重载比较操作符代替逻辑操作符重载。直接使用成员函数代替逻辑操作符重载,使用全居函数对逻辑操作符进行重载。通过对逻辑操作符重载的学习,总结如下:1、C++ 从语法上支持逻辑操作符重载,重载后的逻辑不满足短路法则。2、工程开发中不要重载逻辑操作符;3、通过重载比较操作符替换逻辑操作符重载;4、通过专用成员函数替换逻辑操作符重载。
欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。
以上是关于逻辑操作符的陷阱(三十二)的主要内容,如果未能解决你的问题,请参考以下文章