[C + +] 38 traps of logical operators

Keywords: C++ Programming

Rule

  • Primitive semantics of logical operators

    • Operators have only two values (true and false)
    • The logic expression can determine the final value without complete calculation (short circuit rule)
    • The final result can only be true or false

Programming experiments: logical expressions

#include <iostream>
#include <string>

using namespace std;

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

int main()
{
    if( func(0) && func(1) )
    {
        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;
}
Output: [short circuit rule]
int func(int i) : = 0
Result is false!

int func(int i) : = 1
Result is true!

Overloading logical operators

Can logical operators be overloaded? What's the point of overloading logical operators?

Programming experiment: overloading logical operators

#include <iostream>
#include <string>

using namespace std;

class Test
{
private:
    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) )                     // Pay attention here!
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }
    
    cout << endl;

    if( func(1) || func(0) )                      // Pay attention here!
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }

    return 0;
}
Output:
Test func(Test i) : i.value() = 1
Test func(Test i) : i.value() = 0
Result is false!

Test func(Test i) : i.value() = 0
Test func(Test i) : i.value() = 1
Result is true!

if( func(t0) && func(t1) ) {}
if( func(t0) || func(t1) ) {}

<==>

if( operator && (func(t0), func(t1)) ) {}
if( operator || (func(t0), func(t1)) ) {}

After logical operators are overloaded, they can't fully implement the native semantics!!

  • Some useful suggestions

    • Avoid overloading logical operators in actual engineering development
    • Replace logical operator overloading with overloaded comparison operator
    • Using member functions instead of logical operator overloading
    • Use global functions to overload logical operators [recommended]

Summary

  • C + + syntax supports logical operator overloading
  • The logic operator after overload does not satisfy the short circuit rule
  • Do not overload logical operators in engineering development
  • Replace logical operator overloads with comparison operators
  • Replacing logical operator overloading with special member functions

The above contents refer to the series courses of Ditai Software Institute, please protect the original!

Posted by Silverlime on Wed, 04 Dec 2019 01:25:25 -0800