目录
1. 结论
2. 逻辑操作符重载
1. 结论
前面两次笔记都是 C++ 中可以重载且无副作用的操作符, 本次笔记比较特殊, 主要列出两个 C++ 语法允许重载, 但在工程中不应该 (不允许) 重载的操作符:
逻辑操作符 && 和 ||
逗号操作符, 构成的逗号表达式
这两个操作符在工程中不允许重载的原因是: 重载后无法完全实现操作符的原生语义.
2. 逻辑操作符重载
先来回忆一下逻辑操作符的原生语义
操作数只有 true 和 false 两种值
逻辑表达式不需要完全计算就能确定最终结果(短路法则)
最终结果也只能是 true 或者 false
C++ 语法是允许重载逻辑操作符的, 看下面的示例代码
- #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);
- /*
- * 根据短路法则, 期望的正确输出为:
- * Test func(Test i) : i.value() = 0
- * Result is false!
- */
- if( func(t0) && func(t1) )
- {
- cout << "Result is true!" << endl;
- }
- else
- {
- cout << "Result is false!" << endl;
- }
- cout << endl;
- /*
- * 根据短路法则, 期望的正确输出为:
- * Test func(Test i) : i.value() = 1
- * Result is true!
- */
- if( func(1) || func(0) )
- {
- cout << "Result is true!" << endl;
- }
- else
- {
- cout << "Result is false!" << endl;
- }
- return 0;
- }
代码中注释了我们期待的正确输出, 但实际运行结果一个都没对上, 为什么呢?
操作符重载的本质是通过函数调用扩展操作符的功能, 47 行和 63 行的 if 条件分别等价于
operator && (func(t0), func(t1))
和
operator || (func(t1), func(t0))
重载函数在进入函数体之前必须完成所有参数的计算, 而函数参数的计算顺序是不确定的
短路法则完全失效, 逻辑操作符重载后无法完全实现原生语义
因此, 在工程中应当避免重载逻辑操作符, 建议采用重载比较操作符或提供成员函数的方式, 来代替重载逻辑操作符.
- #include <iostream>
- #include <string>
- using namespace std;
- void func(int i)
- {
- cout <<"func() : i =" << i << endl;
- }
- int main()
- {
- int a[3][3] =
- {
- (0, 1, 2), // 逗号表达式, 等价于 a[3][3] = {2, 5, 8,};
- (3, 4, 5),
- (6, 7, 8)
- };
- int i = 0;
- int j = 0;
- while (i < 5)
- func(i), // 逗号表达式, 等价于 func(i), i++;
- i++;
- cout << endl;
- for (i = 0; i < 3; i++)
- {
- for (j = 0; j < 3; j++)
- {
- cout << a[i][j] << endl;
- }
- }
- cout << endl;
- (i, j) = 6; // 逗号表达式, 等价于 j = 6;
- cout << "i =" << i << endl;
- cout << "j =" << j << endl;
- return 0;
- }
- Class &operator , (const Class &a, const Class &b)
- {
- return const_cast<Class &>(b);
- }
- #include <iostream>
- #include <string>
- using namespace std;
- class Test
- {
- int mValue;
- public:
- Test(int i)
- {
- mValue = i;
- }
- int value()
- {
- return mValue;
- }
- };
- Test &operator , (const Test &a, const Test &b)
- {
- return const_cast<Test &>(b);
- }
- Test func(Test &i)
- {
- cout << "func() : i =" << i.value() << endl;
- return i;
- }
- int main()
- {
- Test t0(0);
- Test t1(1);
- /*
- * 期望的正确输出为:
- * func() : i = 0
- * func() : i = 1
- * 1
- */
- Test tt = (func(t0), func(t1));
- cout << tt.value() << endl;
- return 0;
- }
来源: https://www.cnblogs.com/songhe364826110/p/11581043.html