【C++深度解析】27、不要重载逗号操作符

1 原生的逗号操作符

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

在这里插入图片描述

// 27-1.cpp
#include<iostream>
using namespace std;
void func(int i)
{
    cout << "func(int) : i = " << i << endl;
}
int main()
{
    int a[3][3] = {
        (0, 1, 2),			// 这里是三个逗号表达式,不是大括号
        (3, 4, 5),
        (6, 7, 8)
    };
    int i = 0;
    int j = 0;
    while (i < 5)
      func(i),
    i++;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    (i, j) = 6;						// 逗号表达式,返回值为最后一个子表达式
    cout << "i = " << i << endl;
    cout << "j = " << j << endl;
    return 0;
}
  • 第 10-14 行,初始化数组,使用的是逗号表达式,三个逗号表达式三个返回值,所以只初始化前三个元素,要想给9个元素全部初始化,应该使用大括号。
  • 第 17-19 行,while 循环中是一个逗号表达式,每次循环 i 加1,不是死循环
  • 第 28 行,(i, j) = 6; 返回逗号表达式的最后一个子表达式的值,所以这里是将 6 赋值给 j。
$ g++ 27-1.cpp -o 27-1
$ ./27-1
func(int) : i = 0
func(int) : i = 1
func(int) : i = 2
func(int) : i = 3
func(int) : i = 4
2 5 8 
0 0 0 
0 0 0 
i = 5
j = 6

2 重载逗号操作符

  • 在 C++ 中重载逗号表达式是合法的,使用全局函数进行重载
  • 重载函数的参数必须有一个是类类型
  • 重载函数的返回值类型是引用

在这里插入图片描述

// 27-2.cpp
#include<iostream>
using namespace std;
class Test
{
public:
    Test(int i) : mValue(i) {}
    int value() { return mValue; }
private:
    int mValue;
};
Test& operator , (const Test& a, const Test& b)
{
    return const_cast<Test&>(b);
}
Test func(Test& i)
{
    cout << "func() : i = " << i.value() << endl;
    return i;
}
int main()
{
    Test t0(0);
    Test t1(1);
    Test tt = (func(t0), func(t1));
    cout << "tt.value() = " << tt.value() << endl;
    return 0;
}

我们重载了逗号表达式,将类的对象使用逗号表达式,结果会怎么样呢

编译运行:

$ g++ 27-2.cpp -o 27-2
$ ./27-2
func() : i = 1
func() : i = 0
tt.value() = 1

对于表达式 (func(t0), func(t1)); 编译器 先计算 func(t1) 后计算 func(t1),前面说的逗号表达式按照从左向右的顺序计算每个子表达式的值,这里不是这样的了,为什么呢?

原因我们在上一篇博客中已经讲解了,重载逗号运算符,本质上是函数调用

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

我们将代码 27-2.cpp 中的第 12-15 行注释,也就是将重载的逗号表达式注释,再次编译运行:

$ g++ 27-2.cpp -o 27-2
$ ./27-2
func() : i = 0
func() : i = 1
tt.value() = 1

我们发现没有逗号操作符的重载,一样可以对类使用逗号操作符,并且严格按照从左向右的计算顺序。

所以,在工程中不要重载逗号操作符

3 小结

1、逗号表达式从左向右计算每个子表达式的值
2、逗号表达式的值为最后一个子表达式的值
3、不要重载逗号表达式

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值