第38课 逻辑操作符的陷阱

1. 逻辑运算符原生语义

(1)操作数只有两种值truefalse

(2)逻辑表达式不用完全计算就能确定最终值

(3)最终结果只能是truefalse

 

【编程实验】逻辑表达式   38-1.cpp

#include <iostream>

using namespace std;

 

int func(int i)

{

    cout << "int func(int i): i = " << i << endl;

    return i;

}

 

int main()
{

    //&&的短路:只有一个为0就短路

    //int func(int i): i = 0

    //Result: false   

    if(func(0) && func(1))

    {

        cout << "Result: true" << endl;

    }

    else

    {

        cout << "Result: false" << endl;

    }

   

    cout << endl;

   

    //||的短路:只要1个为1,就短路

    //输出:

    //int func(int i): i = 1

    //Result: true

    if(func(0) || func(1))

    {

        cout << "Result: true" << endl;

    }

    else

    {

        cout << "Result: false" << endl;

    }

 

    return 0;

}

运行结果:

  

 

 

2. 重载逻辑操作符

(1)重载出现的问题及分析

  ①C++通过函数调用扩展操作符的功能

  ②进入函数体前必须完成所有参数的计算

  ③函数参数计算次序不定的

  ④短路法则完全失效

(2)逻辑操作符重载无法完全实现原生的意义

(3)一些有用的建议

  ①实际工程开发中避免重载逻辑操作符

  ②通过重载比较操作符代替逻辑操作符重载

  ③使用成员函数代替逻辑操作符重载

  ④使用全局函数逻辑操作符进行重载

 

【编程实验】操作逻辑运算符   38-2.cpp

#include <iostream>

using namespace std;

 

class Test
{

    int mValue;

public:

    Test(int v){ mValue = v;}

   

    int value()const

    {

        return mValue;

    }

};

 

//利用全局函数重载&&操作符

bool operator && (const Test& lp, const Test& rp)

{

    return lp.value() && rp.value();

}

 

//利用全局函数重载||操作符

bool operator || (const Test& lp, const Test& rp)

{

    return lp.value() || rp.value();

}

 

Test func(Test i)

{

    cout << "int func(Test i): i.value() = " << i.value() << endl;

    return i;

}

 

int main()
{

    Test t0(0);

    Test t1(1);

   

    //输出:(分析:相当于函数调用,进入函数体,参数的值必须被计算出来)

    //int func(Test i): i.value() = 1

    //int func(Test i): i.value() = 0

    //Result: false

    //短路法则完全失效,重载&&改变了其原来应短路的语义

    if(func(t0) && func(t1)) //相当于函数调用operator&&(func(t0), func(t1))

    {

        cout << "Result: true" << endl;

    }

    else

    {

        cout << "Result: false" << endl;

    }

   

    cout << endl;

   

    //输出:(分析:相当于函数调用,进入函数体,参数的值必须被计算出来)

    //int func(Test i): i.value() = 1

    //int func(Test i): i.value() = 0

    //Result: true

    //短路法则完全失效,重载||改变了其原来应短路的语义

    if(func(t0) || func(t1)) //相当于函数调用operator&&(func(t0), func(t1))

    {

        cout << "Result: true" << endl;

    }

    else

    {

        cout << "Result: false" << endl;

    }

 

    return 0;

}

运行结果:

  

 

3. 小结

(1)C++语法上支持逻辑操作符重载

(2)重载后的逻辑操作符不满足短路法则

(3)工程开发中不要重载逻辑操作符

(4)通过重载比较操作符替换逻辑操作符重载

(5)通过专用成员函数替换逻辑操作符的重载

posted @ 2018-12-23 23:24  梦心之魂  阅读(127)  评论(0编辑  收藏  举报