39_逗号操作符的分析

1. 逗号操作符

  • 逗号操作符(,)可以构成逗号表达式:
    • 逗号表达式用于将多个表达式连接为一个表达式
    • 逗号表达式的值为最后一个子表达式的值
    • 逗号表达式中前N-1个子表达式可以没有返回值
    • 逗号表达式按照从左向右的顺序计算每一个子表达式的值

编程说明:逗号表达式的示例

#include 
#include 

using namespace std;

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

int main()
{
    int a[3][3] = {
        (1, 2, 3),
        (4, 5, 6),
        (7, 8, 9)
    };
    
/*
    int a[3][3] = {     // 二维数组正确初始化方法
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
*/
    int i = 0;
    int j = 0;
    
    while (i < 5)
        func(i),

        i++;

    for(i=0; i<3; i++)
    {
        for(j=0; j<3; j++)
        {
            cout << a[i][j] << endl;
        }
    }

    (i, j) = 6;

    cout << "i = " << i << endl;    // i = 5
    cout << "j = " << j << endl;    // j = 6


    return 0;
}

输出结果:

func(int i): i = 0
func(int i): i = 1
func(int i): i = 2
func(int i): i = 3
func(int i): i = 4
3
6
9
0
0
0
0
0
0
i = 3
j = 6

2. 重载逗号操作符

  • 在C++中重载逗号操作符是合法的
  • 使用全局函数对逗号操作符进行重载【特别重要,使用成员函数重载时,g++编译器报错了,原因是什么还没有弄清楚】
  • 重载函数的参数必须又一个类类型
  • 重载函数的返回值类型必须是引用

编程说明:重载逗号操作符

#include 
#include 

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(b);
}

Test func(Test& t)
{
    cout << "func(Test& t) t.value() :" << t.value() << endl;
    
    return t; 
}

int main()
{
    Test t0(0);
    Test t1(1);
    Test t2 = (t0, t1);
        
    cout << "t2: " << t2.value() << endl;
    
    cout << endl;
    
    Test t3 = (func(t0), func(t1));
    
    cout << "t3: " << t3.value() << endl;
    
    
    return 0;
}

输出结果

t2: 1

func(Test& t) t.value() :1
func(Test& t) t.value() :0
t3: 1

总结:重载逗号操作符后虽然两次输出结果都是最后一个表达式的值,但是当通过函数扩展操作符的功能,即Test t3 = (func(t0), func(t1));等价于Test t3 = operator , (func(t0), func(t1));,进入函数体前必须完成所有参数的计算,由于函数参数的计算次序是不定的,得出的输出结果是为func(Test& t) t.value() :1;func(Test& t) t.value() :0,不满足逗号表达式按照从左向右的顺序计算的原生语义。

3. 问题本质分析

  • C++通过函数调用扩展操作符的功能
  • 进入函数体前必须完成所有参数的计算
  • 函数参数的计算次序是不定的
  • 重载后无法严格从左向右计算表达式

工程中不要重载逗号表达式

4. 小结

  • 逗号表达式从左向右顺序计算每个子表达式的值
  • 逗号表达式的值为最后一个子表达式的值
  • 操作符重载无法完全实现逗号操作符的原生意义
  • 工程开发中不要重载逗号操作符

你可能感兴趣的:(39_逗号操作符的分析)