"&&","||"邏輯重載操作符的缺陷 大家,都知道"&&","||"擁有"短路"功能 比如a=(0&&b) : 由於第一個操作數為0,所以不會去判斷b的內容,直接執行a=0 比如a=(-100||b): 由於-100不為0,所以不會去判斷b的內容,直接執行a=1 可以參考下麵代碼: 運行列印: 並 ...
"&&","||"邏輯重載操作符的缺陷
大家,都知道"&&","||"擁有"短路"功能
- 比如a=(0&&b) : 由於第一個操作數為0,所以不會去判斷b的內容,直接執行a=0
- 比如a=(-100||b): 由於-100不為0,所以不會去判斷b的內容,直接執行a=1
可以參考下麵代碼:
int func(int i) { cout << "i = " << i << endl; return i ; } int main() { int a= (func(0)||func(100)); cout<<"a = " << a <<endl; return 0; }
運行列印:
i=0 a=0
並沒有調用func(100)函數,同樣"||"邏輯操作符也具有擁有"短路"功能
而在重載操作符下,"&&","||"就不會具備"短路"功能
參考以下示例:
class Test { int mValue; public: Test(int v) { mValue = v; } int value() const { return mValue; } }; bool operator && (const Test& l, const Test& r) //&&重載操作符 { return l.value() && r.value(); } Test func(Test t) { cout << "value()= " << t.value() << endl; return t; } int main() { Test t0(0); Test t1(1); int b= (func(t0)&&func(t1)); cout<<"b = " << b <<endl; }
列印:
value()=1 //進入func(t1) value()=0 //進入func(t0) b =0
從結果看出,調用了func(t0)和func(t1),並且調用順序是從右往左的.
這是因為執行func(t0)&&func(t1)時:
編譯器實際是執行的operator && (func(t0), func(t1))函數,所以需要進入func()初始化兩個參數
然後通過下麵代碼, 發現參數初始化順序是從右往左的:
int print(int t) { cout<<t<<endl; return t; } void func(int a,int b,int c) { } int main() { func(print(1),print(2),print(3)); return 0; }
運行列印:
","逗號重載操作符的分析
首先回顧下編譯器自帶的","逗號操作符
- 逗號表達式前N-1子表達式不需要返回值
- 逗號表達式從左往右計算,且最終的值等於最後一個表達式的值
比如:
int i=5,b=4; int a =(i++,i++,b+4,b=5,i++); // b=5,且a=(i++)=7,該行運行後,i便等於8 (i,b,a)=10; //a=10,i和b不變
- 逗號表達式,通過()圓括弧來表示
比如:
int a[3][3]={ (1,2,3), (4,5,6), (7,8,9) }; //只初始化了a[0][0]=3, a[0][1]=6, a[0][2]=9
而在重載操作符下, ","逗號就不會具備從左往右計算的功能了
重載逗號註意事項
- 儘量使用全局函數來重載
- 逗號重載函數的參數必須有一個是class類的類型 (讓編譯器知道這個,逗號是用戶重載的)
- 逗號重載函數的返回值類型必須是引用(因為有可能要對返回值進行運算)
- 逗號重載函數的返回值必須是最後一個參數的值(","逗號操作符的特性)
參考以下示例
#include <iostream> #include <string> using namespace std; class Test { int mValue; public: Test(int i) { mValue = i; } int value() { return mValue; } Test operator +(int i) //重載 + 逗號操作符 { Test ret=this->mValue +i; cout<<ret.mValue<<endl; return ret; } }; Test& operator , (const Test& a, const Test& b) //重載 ,逗號操作符 { return const_cast<Test&>(b); } int main() { Test t1(0); Test t2(5); Test t3=(t1+1,t2+1);return 0; }
運行列印:
6 //從最右側執行t2+1 1 //最後執行t1+1
和之前分析的"&&","||"邏輯重載操作符缺陷一樣:
編譯器實際是執行的operator , (t1+1, t2+2)重載操作符函數.
由於初始化參數的順序是從右往左初始化的,所以執行順序變反了,先執行t2+2.
總結:
其實使用編譯器自帶的","逗號操作符,用在對象上也能成功,因為","主要就是用來隔離代碼運行,並返回最後一個參數的值.不會參與對象的運算.
所以在以後的開發中,不要重載","逗號操作符