逗號操做符( , ) 能夠構成逗號表達式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