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


    潜规则:

    在C语言中并没有bool类型。C++中才有。

    逻辑表达式示例:

    添加func函数:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 int func(int i)
     7 {
     8     cout << "int func(int i) : i = " << i << endl;
     9     
    10     return i;
    11 }
    12 
    13 int main()
    14 {
    15     if( func(0) && func(1) )
    16     {
    17         cout << "Result is true!" << endl;
    18     }
    19     else
    20     {
    21         cout << "Result is false!" << endl;
    22     }
    23     
    24     cout << endl;
    25     
    26     if( func(0) || func(1) )
    27     {
    28         cout << "Result is true!" << endl;
    29     }
    30     else
    31     {
    32         cout << "Result is false!" << endl;
    33     }
    34     
    35     return 0;
    36 }

     运行结果:

     重载逻辑操作符:

    C++中允许重载逻辑与和逻辑或,重载逻辑操作符程序入下:

    第42行我们期望只调用func(t0),但是从输出可以看到func(t1)也被调用了。而且先调用的是func(t1)。

    继续演示:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Test
     7 {
     8     int mValue;
     9 public:
    10     Test(int v)
    11     {
    12         mValue = v;
    13     }
    14     int value() const
    15     {
    16         return mValue;
    17     }
    18 };
    19 
    20 bool operator && (const Test& l, const Test& r)
    21 {
    22     return l.value() && r.value();
    23 }
    24 
    25 bool operator || (const Test& l, const Test& r)
    26 {
    27     return l.value() || r.value();
    28 }
    29 
    30 Test func(Test i)
    31 {
    32     cout << "Test func(Test i) : i.value() = " << i.value() << endl;
    33     
    34     return i;
    35 }
    36 
    37 int main()
    38 {
    39     Test t0(0);
    40     Test t1(1);
    41     
    42     if( func(t0) && func(t1) )
    43     {
    44         cout << "Result is true!" << endl;
    45     }
    46     else
    47     {
    48         cout << "Result is false!" << endl;
    49     }
    50     
    51     cout << endl;
    52     
    53     if( func(1) || func(0) )
    54     {
    55         cout << "Result is true!" << endl;
    56     }
    57     else
    58     {
    59         cout << "Result is false!" << endl;
    60     }
    61     
    62     return 0;
    63 }

     运行结果如下:

     可以看到逻辑或也调用了两次,而且是先调用的func(0)。变成从右向左开始计算了。逻辑操作符本应从左向右计算。

    问题的本质分析:

    我们将&&和||换成函数调用的方式就容易理解了,这也是操作符重载的本质。

    运行结果如下:

    可以看到跟直接使用操作符的方式是一样的。

    工程中最好不要重载逻辑与和逻辑或,因为不再满足短路规则。

    逻辑操作符在重载后无法实现原生的语义。

    建议:

     通过重载比较操作符,使一个对象和true或者false去比较,这样也可以实现需求。

    小结:

  • 相关阅读:
    一本通 1259:【例9.3】求最长不下降序列
    一本通 1258:【例9.2】数字金字塔
    洛谷 P1198 [JSOI2008]最大数
    洛谷 P2863 [USACO06JAN]牛的舞会The Cow Prom
    【BZOJ1062】糖果雨(NOI2008)-数形结合+二维树状数组
    【BZOJ4070】雅加达的摩天楼(APIO2015)-分块+最短路
    【BZOJ2326】数学作业(HNOI2011)-递推+矩阵快速幂
    【BZOJ2734】集合选数(HNOI2012)-状压DP
    【BZOJ3213】抛硬币(ZJOI2013)-期望DP+KMP+高精度
    【BZOJ3590】Quare(SNOI2013)-状压DP
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9573751.html
Copyright © 2020-2023  润新知