28 逻辑操作符的陷阱
1 逻辑运算符规则
-
逻辑运算符(
&&
,||
,!
)的原生语义- 操作数只有两种值(
true
和false
) - 逻辑表达式不用完全计算就能确定最终值
- 最终结果只能是
true
或者false
- 操作数只有两种值(
-
示例1:逻辑表达式
-
Demo
#include <iostream> #include <string> using namespace std; int func(int i) { cout << "int func(int i) : i = " << i << endl; return i; } int main() { if( 0 && 1 ) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } cout << endl; if( 0 || 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; } cout << endl; if( func(0) || func(1) ) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } return 0; } -
编译运行
Result is false! Result is true! int func(int i) : i = 0 Result is false! int func(int i) : i = 0 int func(int i) : i = 1 Result is true!
-
2 重载逻辑表达式
-
【问题】逻辑操作符可以重载么?重载逻辑操作符有什么意义?
- 不可以,会引入陷阱,违背了逻辑操作符的原生语义
-
示例2:重载逻辑操作符
-
Demo
#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& l, const Test& r) { return l.value() && r.value(); } // 尝试利用全局函数进行重载|| bool operator || (const Test& l, const Test& r) { return l.value() || r.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) ) // <=>函数调用形式: if(operator && (func(to),func(t1))) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } cout << endl; if( func(1) || func(0) ) // <=>函数调用形式: if(operator || (func(to),func(t1))) { cout << "Result is true!" << endl; } else { cout << "Result is false!" << endl; } return 0; } -
编译运行
Test func(Test t) : t.value = 1 Test func(Test t) : t.value = 0 Result is false! Test func(Test t) : t.value = 1 Test func(Test t) : t.value = 0 Result is true! -
问题:短路法则失效,且调用顺序不定
-
-
问题的本质分析
- C++ 通过函数调用扩展操作符的功能
- 进入函数体前必须完成所有参数的计算
- 函数参数的计算次序是不定的
- 短路法则完全失效
-
逻辑操作符重载后无法完全实现原生语义
-
Tips
- 实际工程开发中避免重载逻辑操作符
- 通过重载比较操作符(与
true
或false
比较)代替逻辑操作符重载 - 直接使用成员函数代替逻辑操作符重载
- 使用全局函数对逻辑操作符进行重载
本文作者:nxgy
本文链接:https://www.cnblogs.com/bky-hbq/p/13903871.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步