逗号操做符( , ) 能够构成逗号表达式ios
- 逗号表达式用于将多个子表达式链接为一个表达式
- 逗号表达式的值为最后一个表达式的值
- 逗号表达式中的前 N-1 个子表达式能够没有返回值
- 逗号表达式按照从左向右的顺序计算每一个子表达式的值
exp1, exp2, exp3, ..., 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), // 注意这里! (3, 4, 5), (6, 7, 8) }; 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; }
输出: 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
int a[3][3] = { (0, 1, 2), (3, 4, 5), (6, 7, 8) };
<==>segmentfault
int a[3][3] = { (2), (5), (8) };
修正:函数
int a[3][3] = { {0, 1, 2}, {3, 4, 5}, {6, 7, 8} };
- 在 C++ 中重载逗号操做符是合法的
- 使用全局函数对逗号操做符进行重载【推荐】
- 重载函数的参数必须有一个是类类型
- 重载函数的返回值类型必须是引用
class& operator , (const Class& a, const Class& b) { return const_cast<Class&>(b); }
#include <iostream> #include <string> using namespace std; class Test { private: int mValue; public: Test(int i) { mValue = i; } int value() { return mValue; } }; Test& func(Test& i) { cout << "func() : i.value() = " << 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.value() = 1 func() : i.value() = 0 1 分析: 重载后的逗号表达式中的子表达式为何没有从左向右的顺序执行呢?
问题的本质分析spa
- C++ 经过函数调用扩展操做符的功能
- 进入函数体前必须完成全部参数的计算
- 函数参数的计算次序是不定的
- 重载后没法严格按照从左向右的顺序计算表达式
Test tt = (func(t0), func(t1));
<==>code
Test tt = operator , (func(t0), func(t1));
工程中不要重载逗号操做符!开发
#include <iostream> #include <string> using namespace std; class Test { private: int mValue; public: Test(int i) { mValue = i; } int value() { return mValue; } }; Test& func(Test& i) { cout << "func() : i.value() = " << i.value() << endl; return i; } int main() { Test t0(0); Test t1(1); Test tt = (func(t0), func(t1)); // Test tt = func(t1) cout << tt.value() << endl; return 0; }
输出: func() : i.value() = 0 func() : i.value() = 1 1
发现了什么?
大多数状况下,赋值操做符的重载是没有意义的。get
- 逗号表达式从左向右顺序计算每一个子表达式的值
- 逗号表达式的值为最后一个子表达式的值
- 操做符重载没法彻底实现逗号操做符的原生意义
- 工程开发中不要重载逗号操做符
以上内容参考狄泰软件学院系列课程,请你们保护原创!string