第38课.逻辑操作符的陷阱

eg:

#include <iostream>
#include <string>

using namespace std;

class Test
{
    int mValue;
public:
    Test (int v)
    {
        mValue = v;
    }
    
    int value() const       //因为重载的逻辑操作符的参数是const对象。const对象只能调用const函数。
    {
        return mValue;
    }
};

bool operator && (const Test& l, const Test& r)            //const对象
{
    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(0) && func(1))            //理论上:0 && 1 只执行func(0)。执行完后,短路。这句语句就结束了。但实际上fun(0)和func(1)都执行了???
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }
    
    cout << endl;
    
    if( func(1) || func(0) )          //理论上:1 && 0 只执行func(1)。执行完后,短路。这句语句就结束了。但实际上fun(0)和func(1)都执行了???
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }
    
    return 0;
}

问题:为什么重载后会出现和理论上相互违背的事情呢?短路规则不在起作用?为什么先调用的后面的,在调用的前面的?

答案:
a.重载逻辑操作符的时候,需要将重载函数所需的两个参数传递个重载函数进行调用。而函数的参数在进入函数体前必须完成所有参数的计算。所有导致函数的短路法则不起作用。这样才有了上诉的func(0)和fun(1)两者都被调用的现象产生。
b.那为什么函数的参数的计算顺序是从右向左的呢?因为函数参数的计算顺序是不定的。这里只是碰巧编译决定了,他们是从右到左的。

结论:不推荐使用重载去重载逻辑操作符。因为重载无法实现短路法则。

posted @ 2019-11-21 10:35  人民广场的二道贩子  阅读(149)  评论(0编辑  收藏  举报