今天来学习C++中的逗号操作符。那么什么是逗号操作符呢?

*逗号操作符(,)可以构成逗号表达式

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

    exp1,exp2,……,expn-1,expn

下面我们还是以一个例子来说明逗号表达式概念与性质:

#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),  //注意,这里的二维数组的初始化用的是(),而不是{},所以里面的内容构成逗号表达式(0,1,2)的值就为2.
        (3,4,5),  //(3,4,5)的值为5
        (6,7,8)   //(6,7,8)的值为8,所以这个数组实际上,只初始化了前三个数,后面的数全为0;
    };

    int i = 0;
    int j = 0;

    while(i < 5)
        func(i),  /*注意这里是逗号,而不是分号,所以这个表达式等同于{func(i);i++}*/

    i++;

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

    (i,j) = 6;     //此处给逗号表达式赋值,实际上是给j赋值,而i值不变
    cout << "i = " << i << endl;
    cout << "j = " << j << endl;
    return 0;
}

上述程序运行结果为:
func() : i = 0
func() : i = 1
func() : i = 2
func() : i = 3
func() : i = 4
2
5
8
0
0
0
0
0
0
i = 3
j = 6

由运行结果,以及程序内容的分析,得以验证上面所说的逗号表达式的性质。

那么,我们来试一下逗号表达式的重载,看看会出现什么结果:

#include <iostream>
#include <string>

using namespace std;

class Test
{
        int mValue;
public:
        Test(int i)
        {
                mValue = i;
        }
        int Value()
        {
                return mValue;
        }
};

Test func(Test& i)
{
        cout << "func() : i = " << i.Value() << endl;
        return i;
}

Test& operator , (const Test& a, const Test& b)  //重载逗号操作符
{
        return const_cast<Test&>(b);
}

int main()
{
    Test t0(0);
    Test t1(1);
    Test tt = (func(t0),func(t1));

    cout << tt.Value() << endl;
    return 0;
}

运行结果:
func() : i = 1
func() : i = 0
1
由程序的分析,以及运行结果得知,我们的逗号操作符确实是返回的是最后一个子表达式的值,但是有一点,却变了,子表达式的运行的次序,可以看出,是先运行func(t1),后运行func(t0),这是为什么呢?

问题本质的分析:

  1. C++通过函数调用扩展操作符的功能
  2. 进入函数体前必须完成所有参数的计算
  3. 函数参数的计算次序是不定的
  4. 重载后无法严格按照从左向右的次序计算表达式(这跟编译器有关,也有可能会从左向右计算)

而当我们把上面的重载函数去掉,不用重载的逗号表达式,直接用原有的逗号表达式,结果就是:
func() : i = 0
func() : i = 1
1


总结:

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

想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题。