重載的運算符必須接受至少一個自定義類型。接受的參數都為內置類型的運算符無法被重載。
運算符作為類的成員函數被重載時,類的對象就作為第一個參數。注意此時函數的返回方式。
重載++a會調用operator++(a),重載a++會調用operator++(a, int),其中第二個int參數是不會被用到的,只是用來區分前綴和後綴調用。--的重載也是一樣。
=和[]只能作為成員函數被重載。()只能作為成員函數被重載,可以帶任意多個參數。(若可以不作為成員函數被重載,則對於內置類型的運算就可以被重載,這是沒有意義的)
->和->*也只能作為成員函數被重載,但對返回值有一定的限制。
.和.*不能被重載
返回值優化:
return tmp;
這樣編譯器需要三步才能完成(構造,拷貝,析構),而return Integer(left.i + right.i);則只需要一步
所有其他的二元運算符 推薦作為非成員
當對象還沒有被創建時,=調用的是構造函數或拷貝構造函數,為的是初始化對象;當對象已被創建時,=調用的才是operator=。因此
這樣的寫法清晰。
在重載賦值運算符時,首先檢查是否是對自身賦值是個好習慣。
當對象中有指針時,拷貝構造函數通常需要連同復制出指針所指向的內容。而當此內容很大時,通常采用引用計數的方法,只在需要修改數據且引用數大於1時才復制內容。這種技術被稱為copy-on-write。
當構造函數接受一個其他類型的對象作為參數時,編譯器可以用它來進行自動類型轉換。如果不需要這樣的自動轉換,在構造函數前加上explicit。
也可以重載operator 類型名來定義自動類型轉換。由於這種類型轉換是由源對象完成的(不像構造函數的類型轉換是由目標對象完成的),因此可以完成自定義對象到內置類型的轉換。
運算符重載為非成員函數時,運算符兩邊都可以進行自動類型轉換。
提供自動類型轉換時注意兩種類型之間只需提供一條轉換路徑,否則會出現二義性錯誤。
#includeusing namespace std; template class Array { public: // 重載[]運算符 T& operator [] (size_t num) { return m_arr[num]; } // 提供一個常版本的[]運算符 T const& operator [] (size_t num) const { // 為了維護方便,盡量復用函數 return const_cast(*this)[num]; } int length(void) const { return S; } // 由於左操作數是標准提供的類,最好用友元的方式實現<<重載 friend ostream& operator << (ostream& os, Array const& arr) { for (size_t i = 0; i < S; ++i) cout << arr[i] << ' '; cout << endl; } private: T m_arr[S]; };