C++——逻辑操作符的危险

来源:互联网 发布:魔兽世界画面优化 编辑:程序博客网 时间:2024/05/16 05:34

C++的逻辑操作符我们在C语言里就一直用,从来没遇到过什么危险的事,因为一直是按照想法执行的。为什么会有危险。因为C++里操作符的重载。先来了解一下前提。

1操作符的重载的本质是函数的调用。

2逻辑操作符从做往右执行,满足短路规则,即不用计算完就可能得到结果。

这里所说的逻辑操作符就是因为操作符的重载出现的。我们通过一个例子说明。

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);        /*原生的逻辑操作符在这里只会执行func(t0),就会得出结果*/    /*执行结果是两个函数都执行了,而且从右向左执行,结果是对的*/    /*虽然结果对,但是改变了操作符的原生语义,所以工程里不要重载逻辑操作符*/    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;}
为什么上述的都会执行呢,不满足短路呢,这是因为重载是函数,所以进入函数体前必须计完成参数的计算,所以操作符两边的两个函数都需要运行得到具体的值。那为什么执行的顺序也不对,因为此时函数参数的求值的顺序是不确定的。

那我们需要判断对象的一些情况时,推荐以下的方法。

1类成员函数重载比较操作符

2直接使用某个类成员函数实现这个功能

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

上面都说明了重载的时候是执行函数,进入函数体前必须完成所有的参数计算,而参数计算的顺序又是不确定的,所以如果我们要重载逗号操作符也是不能满足它的原生语义,所以我们也不要重载逗号操作符,因为如果我们重载,我们可以正确的返回应该返回的结果,即最右边的表达式的值的引用,但是我们不能保证重载后是从左至右依次执行的。

所以一定不要在工程里重载逻辑操作符和逗号操作符。