zoukankan      html  css  js  c++  java
  • 20.C++- "&&","||"逻辑重载操作符的缺陷、","逗号重载操作符的分析

    "&&","||"逻辑重载操作符的缺陷

    大家,都知道"&&","||"拥有"短路"功能

    • 比如a=(0&&b) :  由于第一个操作数为0,所以不会去判断b的内容,直接执行a=0
    • 比如a=(-100||b): 由于-100不为0,所以不会去判断b的内容,直接执行a=1

    可以参考下面代码:

    int func(int i)
    {
        cout << "i = " << i  << endl;
        return i ;
    }
    
    int main()
    {
        int a= (func(0)||func(100));
        cout<<"a = " << a <<endl;
        return 0;
    }

    运行打印:

    i=0
    a=0

    并没有调用func(100)函数,同样"||"逻辑操作符也具有拥有"短路"功能

    而在重载操作符下,"&&","||"就不会具备"短路"功能

    参考以下示例:

    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();
    }
    
    Test func(Test t)
    {
         cout << "value()= " << t.value()  << endl;
         return t;
    }
    
    int main()
    {
      Test t0(0);
      Test t1(1);
      int b= (func(t0)&&func(t1));
      cout<<"b = " << b <<endl;
    }

    打印:

    value()=1             //进入func(t1)
    value()=0             //进入func(t0)
    b =0

    从结果看出,调用了func(t0)func(t1),并且调用顺序是从右往左的.

    这是因为执行func(t0)&&func(t1)时:

    编译器实际是执行的operator && (func(t0), func(t1))函数,所以需要进入func()初始化两个参数

    然后通过下面代码, 发现参数初始化顺序是从右往左的:

    int print(int t)
    {
             cout<<t<<endl;
             return t;
    }
    void func(int a,int b,int c)
    {  }
    
    int main()
    {
       func(print(1),print(2),print(3));  
       return 0;
    }

    运行打印:

     

      

    ","逗号重载操作符的分析

    首先回顾下编译器自带的","逗号操作符

    • 逗号表达式前N-1子表达式不需要返回值
    • 逗号表达式从左往右计算,且最终的值等于最后一个表达式的值

    比如:

    int i=5,b=4;
    int a =(i++,i++,b+4,b=5,i++);         // b=5,且a=(i++)=7,该行运行后,i便等于8
    (i,b,a)=10;                                       //a=10,i和b不变
    • 逗号表达式,通过()圆括号来表示

    比如:

    int a[3][3]={ (1,2,3),      
                  (4,5,6),
                  (7,8,9) };    //只初始化了a[0][0]=3, a[0][1]=6, a[0][2]=9

    而在重载操作符下, ","逗号就不会具备从左往右计算的功能了

    重载逗号注意事项

    • 尽量使用全局函数来重载
    • 逗号重载函数的参数必须有一个是class类的类型 (让编译器知道这个,逗号是用户重载的)
    • 逗号重载函数的返回值类型必须是引用(因为有可能要对返回值进行运算)
    • 逗号重载函数的返回值必须是最后一个参数的值(","逗号操作符的特性)

    参考以下示例

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Test
    {
        int mValue;
    public:
        Test(int i)
        {
            mValue = i;
        }
    
        int value()
        {
            return mValue;
        }
    
      Test  operator +(int i)                              //重载 + 逗号操作符
      {
          Test ret=this->mValue +i;
          cout<<ret.mValue<<endl;
         return ret;
      }
    
    };
    
    Test& operator , (const Test& a, const Test& b) //重载 ,逗号操作符
    {
        return const_cast<Test&>(b);
    }
    
    int main()
    {  
        Test t1(0);
        Test t2(5);
        Test t3=(t1+1,t2+1);return 0;
    }

    运行打印:

    6                         //从最右侧执行t2+1
    1                         //最后执行t1+1

    和之前分析的"&&","||"逻辑重载操作符缺陷一样:

    编译器实际是执行的operator , (t1+1, t2+2)重载操作符函数.

    由于初始化参数的顺序是从右往左初始化的,所以执行顺序变反了,先执行t2+2.

    总结:

    其实使用编译器自带的","逗号操作符,用在对象上也能成功,因为","主要就是用来隔离代码运行,并返回最后一个参数的值.不会参与对象的运算.

    所以在以后的开发中,不要重载","逗号操作符

  • 相关阅读:
    小儿吃鸡蛋食积案
    女子经前胀痛脸上红斑案
    小儿外感咳嗽咽痛案
    顽固偏头痛案
    交通心肾治失眠
    小儿扁桃体高热兼咳嗽案
    过敏疾患与太少两感相合
    经前乳胀案
    女子黃带案
    小儿外感后频繁眨眼案
  • 原文地址:https://www.cnblogs.com/lifexy/p/8660910.html
Copyright © 2011-2022 走看看