• 第39课 逗号操作符的分析


    1. 逗号操作符(

    (1)逗号表达式用于将多个子表达式连接为一个表达式

    (2)逗号表达式最后一个子表达式的值

    (3)逗号表达式N-1个子表达式可以没有返回值,最后一个要有返回值

    (4)逗号表达式按照从左向右的顺序计算每个子表达式的值

            exp1,exp2,exp3,…,expN;

      1 #include <iostream>
      2 
      3 using namespace std;
      4 
      5 void func(int i)
      6 {
      7     cout << "func(): i = " << i << endl;
      8 }
      9 
     10 int main()
     11 {
     12     #include <iostream>
     13 
     14 using namespace std;
     15 
     16 void func(int i)
     17 {
     18     cout << "func(): i = " << i << endl;
     19 }
     20 
     21 int main()
     22 {
     23     int a[3][3] = {
     24          
     25         (0, 1, 2), //注意这里是逗号,不是花括号  表达式值:2
     26 
     27         (3, 4, 5), //相当于只给数组前三个元素赋值   表达式值:5
     28 
     29         (6, 7 ,8)  //分别是2、5、8,其余为0  表达式值:8
     30     };
     31 
     32 /*    int a[3][3] = {   这才是初始化
     33 
     34         {0, 1, 2},
     35 
     36         {3, 4, 5},
     37 
     38         {6, 7 ,8 }
     39     };*/
     40 
     41     int i = 0;
     42     int j = 0;
     43 
     44     while (i < 5)
     45 
     46         func(i),  //这里与下一行的i++组合一个表达式
     47 
     48         i++;          //所以while不会死循环
     49 
     50     等价于while(i < 5)
     51         {
     52             func(i);
     53             i++;
     54         }
     55 
     56 
     57     for (int i = 0; i < 3; i++)
     58     {
     59         for (int j = 0; j < 3; j++)
     60         {
     61             cout << a[i][j] << endl; //2,5,8,0,0,0,0,0,0
     62         }
     63     }
     64 
     65     (i, j) = 6; //合法:逗号表达式返回j,相当于j = 6
     66 
     67     cout << "i = " << i << endl;  //5
     68 
     69     cout << "j = " << j << endl;  //6
     70 
     71 
     72 
     73     return 0;
     74 
     75 }
     76 
     77     int i = 0;
     78     int j = 0;
     79 
     80     while (i < 5)
     81 
     82         func(i),  //这里与下一行的i++组合一个表达式
     83 
     84         i++;          //所以while不会死循环
     85 
     86     等价于while(i < 5)
     87         {
     88             func(i);
     89             i++;
     90         }
     91 
     92 
     93     for (int i = 0; i < 3; i++)
     94     {
     95         for (int j = 0; j < 3; j++)
     96         {
     97             cout << a[i][j] << endl; //2,5,8,0,0,0,0,0,0
     98         }
     99     }
    100 
    101     (i, j) = 6; //合法:逗号表达式返回j,相当于j = 6
    102 
    103     cout << "i = " << i << endl;  //5
    104 
    105     cout << "j = " << j << endl;  //6
    106 
    107 
    108 
    109     return 0;
    110 
    111 }

    运行结果:

      

    2. 重载逗号操作符

    (1)在C++中重载逗号操作符合法

    (2)使用全局函数对逗号操作符进行重载

    (3)重载函数参数必须有一个是类类型(因为这里指的是类的操作符重载)

    (4)重载函数返回值类型必须是引用

    ClassType& operator ,(const ClassType& a, const ClassType& b)    全局函数进行重载
    {
    
        return const_cast<ClassType&>(b); //逗号表达式,返回右操作符,必须强制转换,函数返回值是引用,所以去除const属性
    
    }
     1 #include<iostream> 
     2 #include<string>
     3 
     4 using namespace std;
     5 
     6 //重载需要类类型,定义类
     7 class Test
     8 {
     9     int mvalue;
    10 public:
    11     Test(int i)
    12     {
    13         mvalue = i;
    14     }
    15     int value()
    16     {
    17         return mvalue;
    18     }
    19 };
    20 
    21 //全局函数进行逗号操作符重载
    22 Test& operator , (const Test& a, const Test& b) // 1、参数必须有一个为类类型
    23 {
    24     return const_cast<Test&>(b);   //2,返回值是Test引用,所以要强制类型转换去掉const属性
    25 }
    26 
    27 Test func(Test& i)   //
    28 {
    29     cout << "func() : i = " << i.value() << endl;
    30 
    31     return i;
    32 }
    33 
    34 int main()
    35 {
    36     Test t0(0);
    37     Test t1(1);
    38 
    39 //  Test tt=(t0,t1);  //逗号表达式,等价于Test tt=t1;
    40 
    41     //为什么先调用右边????逗号操作符重载中间发生变化,变成从右向左调用,违背逗号表达式
    42 
    43     //因重载操作符的本质相当于函数调用,所以
    44 
    45     //相当于Test tt = operator,(func(t0(0)), func(t1(1)));//函数调用!
    46 
    47     //当进入函数体,参数的值必须被计算,而两个参数func(t0(0))和func(t1(1))
    48 
    49     //的计算次序是不确定的,在g++编译下,输出
    50 
    51     //func(): i = 1
    52 
    53     //func(): i = 0
    54     
    55     Test tt = (func(t0), func(t1));   //逗号表达式,等价于Test tt=func(t1); 逗号表达式,本意是从左向右计算
    56                                     
    57 
    58                                     
    59   //  Test tt = (operator , (func(t0), func(t1)));                                                                    //等价于Test tt = (operator , func(t0), func(t1));  
    60 
    61     cout << tt.value() << endl; //1虽然结果是正确的,但中间的计算过程与
    62 
    63                                 //逗号表达式原义从左向右计算要求有可能不一致。
    64 
    65     return 0;
    66 }

    3. 重载时出现的问题与本质分析

    (1)C++通过函数调用扩展操作符的功能

    (2)进入函数体前必须完成所有参数的计算

    (3)函数参数的计算次序是不定的

    (4)重载后无法严格从左向右计算表达式,不重载时返回能从左向右,所以重载逗号操作符完全无意义,违背逗号表达式原生语义

     实验:工程中,完全没有必要重载逗号操作符

     1 #include<iostream> 
     2 #include<string>
     3 using namespace std;
     4 //全局函数进行逗号操作符重载
     5 
     6 class Test
     7 {
     8     int mvalue;
     9 public:
    10     Test(int i)
    11     {
    12         mvalue = i;
    13     }
    14     int value()
    15     {
    16         return mvalue;
    17     }
    18 };
    19 
    20 //不要进行逗号操作符重载
    21 /*
    22 Test& operator , (const Test& a, const Test& b)
    23 {
    24     return const_cast<Test&>(b);                 //返回值是Test 引用,所以要强制类型转换去掉const属性,用const_cast
    25 }
    26 */
    27 
    28 Test func(Test& i)
    29 {
    30     cout << "func() : i = " << i.value() << endl;
    31     return i;
    32 }
    33 
    34 int main()
    35 {
    36     Test t0(0);
    37     Test t1(1);
    38      
    39     Test tt = (func(t0), func(t1));        
    40                                                                     
    41 //    Test tt = (operator , (func(t0), func(t1)));                                                            
    42 
    43     cout << tt.value() << endl;      //func(): i=0
    44                                      //func(): i=1
    45 
    46     去掉重载,结果与没有重载之前结果一致--------------工程中,完全没有必要重载逗号操作符
    47 
    48     return 0;
    49 }

    4. 小结

    (1)逗号表达式从左向右顺序计算每个子表达式的值

    (2)逗号表达式最后一个子表达式的值

    (3)操作符重载无法完全实现逗号操作符的原生意义从左向右计算

    (4)工程开发中不要重载逗号操作符

  • 相关阅读:
    [TC_SRM_466]DrawingBlackCrosses
    [POJ3254]Corn Fields
    [openjudge6043]哆啦A梦的时光机
    网络流 24 题汇总(LOJ 上只有 22 题???)
    Xadmin组件的url设计
    《今日简史》一、旧故事已然崩坏,新故事尚未构建
    《人类简史》二、认知革命——上帝之手的秘密
    ORM复习
    无拘无束的爱情
    使用代理导致IE host被修改问题的解决方案
  • 原文地址:https://www.cnblogs.com/liuyueyue/p/13382933.html
Copyright © 2020-2023  润新知