以下運算符可重載:
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ -- , ->* -> () [] new new[] delete delete[]
不可重載(5 個):
sizeof - 長度運算符?: - 條件運算符. - 成員選擇運算符.* - 成員指針選擇運算符:: - 域解析運算符| # | 規則 | 說明 |
|---|---|---|
| 1 | 不改變優先級與結合性 | c1 + c2 * c3 仍先算乘法,同內建型別 |
| 2 | 不改變操作數個數/位置 | 一元仍一元,二元仍二元,左/右操作數位置固定 |
| 3 | 不可有預設參數 | 否則改變操作數個數,違反運算符語義 |
| 4 | 不可為內建型別重新定義 | int operator+(int,int) 非法,防止 4+3 語義混亂 |
| 5 | 至少一個操作數為用戶定義型別 | 全域函數重載時強制要求,區分自定義與內建 |
| 6 | 特定運算符只能作成員函數 | = [] () -> 四大運算符限定為成員 |
| 形式 | 一元運算符 | 二元運算符 | 隱含參數 |
|---|---|---|---|
| 成員函數 | 0 參數 | 1 參數 | this 指針 |
| 全域函數 | 1 參數 | 2 參數 | 無 |
| 場景 | 推薦形式 | 理由 |
|---|---|---|
= [] () -> | 成員函數 | 語法強制要求 |
對稱運算符 (+ - * / == !=) | 全域函數 | 左右操作數地位對等,支援隱式轉換 |
修改左操作數 (+= -= *=) | 成員函數 | 自然表達 this 修改 |
左操作數非類型 (ostream<<) | 全域函數 | 無法修改標準庫類 |
| 類型轉換運算符 | 成員函數 | 只能為成員 |
因需訪問 private/protected 成員:
class Complex {
friend Complex operator+(const Complex&, const Complex&);
friend ostream& operator<<(ostream&, const Complex&);
// ...
};
// 錯誤:嘗試重載內建型別運算符
int operator+(int a, int b) { return a - b; } // 編譯錯誤!
// 錯誤:改變操作數個數
Complex operator+(Complex a, Complex b, Complex c); // 三元+ 非法
// 錯誤:預設參數
Complex operator+(Complex a, Complex b = Complex()); // 非法
運算符重載雖強大,但受嚴格規則約束。核心原則:保持語義直觀、不破壞內建行為、正確選擇成員/全域形式。掌握可重載清單、六大限制、參數差異與選擇策略,才能編寫符合 C++ 慣用法、不驚訝用戶的運算符重載代碼。