zoukankan      html  css  js  c++  java
  • 28 逻辑操作符的陷阱

    1 逻辑运算符规则

    • 逻辑运算符(&&||!)的原生语义

      • 操作数只有两种值(truefalse
      • 逻辑表达式不用完全计算就能确定最终值
      • 最终结果只能是 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

      • 实际工程开发中避免重载逻辑操作符
      • 通过重载比较操作符(与 truefalse 比较)代替逻辑操作符重载
      • 直接使用成员函数代替逻辑操作符重载
      • 使用全局函数对逻辑操作符进行重载
  • 相关阅读:
    Day-5 python
    Day-2 python
    OCR技术浅探
    yael图像检索库
    编程语言
    BOW模型和SIFT特征
    汉明嵌入
    Lua1.1 Lua 的参考手册 (三)
    Lua1.1 Lua 的参考手册 (二)
    Lua1.1 Lua 的参考手册 (一)
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13903871.html
Copyright © 2011-2022 走看看