1、逗号操作符
- 逗号操作符(,)可以构成逗号表达式
— 逗号表达式用于将多个子表达式连接为一个表达式
— 逗号表达式的值为最后一个子表达式的值
— 逗号表达式的前 N-1 个子表达式可以没有返回值
— 逗号表达式按照从左向右的顺序计算每个子表达式的值
程序一:逗号表达式的知识回顾
#include <iostream>
#include <string>
using namespace std;
void 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 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;
cout << "j = " << j << endl;
return 0;
}
修改如下:
#include <iostream>
#include <string>
using namespace std;
void 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 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;
cout << "j = " << j << endl;
return 0;
}
2、重载逗号操作符
- 在C++中重载逗号操作符是合法的
- 使用全局函数对逗号操作符进行重载
- 重载函数的参数必须有一个是类类型
- 重载函数的返回值类型必须是引用(1、看返回值类型 2、和函数形参一致)
Class& operator , (const Class& a, const Class& b)
{
return const_cast<Class&>(b);
}
#include <iostream>
#include <string>
using namespace std;
class Test
{
private:
int i;
public:
Test(int i = 0)
{
this->i = i;
}
int getI()
{
return i;
}
};
Test func(Test& i)
{
cout << "func(Test& i):i.getI() = " << i.getI() << 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 t2 = (func(t0), func(t1));
cout << t2.getI() << endl;
return 0;
}
分析:
在上面程序的第32行代码,我们从我们的两个输出函数发现了一些端倪,产生了和前一章的逻辑操作符的重载一样的问题。本来希望它会从左向右输出,结果还是从右向左输出。产生的原因都是一样的,因为函数的参数运算的次序是不一定的。可以把它换成另一种形式更好理解:Test t2 = operator , (func(t0), func(t1));
。
- 问题的本质
1、C++通过函数调用扩展操作符的功能
2、进入函数体之前必须完成所有参数的计算
3、函数参数的计算次序是不定的
4、短路法则完全失效
假如我们不重载逗号操作符,我们看一下会发生什么?
#include <iostream>
#include <string>
using namespace std;
class Test
{
private:
int i;
public:
Test(int i = 0)
{
this->i = i;
}
int getI()
{
return i;
}
};
Test func(Test& i)
{
cout << "func(Test& i):i.getI() = " << i.getI() << endl;
return i;
}
int main()
{
Test t0(0);
Test t1(1);
Test t2 = (func(t0), func(t1));
cout << t2.getI() << endl;
return 0;
}
看到输出结果,我笑了。你重载反而会报错,你不重载输出还是对的。
-
工程中不要重载逗号表达式
-
小结
— 逗号表达式从左向右顺序的计算每个子表达式的值
— 逗号表达式的值为最后一个子表达式的值
— 操作符重载无法完全实现逗号操作符的原生意义
— 工程开发中不要重载逗号操作符