C++_運算子過載的注意事項
2、過載操作符函式為成員函式主要是你需要操作類內部的成員,
必須是成員函式或友元函式才行。
3、至於由深淺拷貝的原因要使其成為成員函式,這個不知道。
4、如果運算子被過載為全域性函式,那麼只有一個引數的運算子叫做一元運算子,有兩個引數的運算子叫做二元運算子。
如果運算子被過載為類的成員函式,那麼一元運算子沒有引數,二元運算子只有一個右側引數,因為物件自己成了左側引數。
從語法上講,運算子既可以定義為全域性函式,也可以定義為成員函式。文獻[Murray , p44-p47]對此問題作了較多的闡述,並總結了表8-4-1的規則。
運算子
規則
所有的一元運算子
建議過載為成員函式
= () [] ->
只能過載為成員函式
+= -= /= *= &= |= ~= %= >>= <<=
建議過載為成員函式
所有其它運算子
建議過載為全域性函式
第四點來自 http://shake863.iteye.com/blog/213590
簡單地說,C++標準規定要這樣使用,但為什麼要這樣規定,請看下面:
1:對於賦值操作符(=)--比較特別,因為任何類如果不提供顯示的拷貝賦值(即過載=),則編譯器會隱式地提供一個。這樣的話,如果你再通過友元宣告,進行全域性的定義會造成呼叫二義性(即使允許,編譯也會出錯)。
2:對於所有樓主提到的操作符(=,[],(),->),只能宣告為成員函式是為了避免不合法的書寫通過編譯(這是推測出的原因,更深層的可能要研究 C++ 的設計了)。這涉及到 C++ 中型別的隱式轉換。下面通過程式碼例子說明:
C/C++ code ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <iostream>
class X
{
public :
X(){}
X( int ){} // int 型別可以被隱式轉換成 X
friend bool operator<( const X& x1, const X& x2) { return true ; } // 只是測試,無意義
};
class Y
{
public :
Y(){}
Y( int ){} // int 型別可以被隱式轉換成 Y
|