運算符重載基礎
運算符重載本質是函數重載,函數名為 operator@(@ 為運算符)。賦予用戶定義類型直觀的運算語法。
可重載 / 不可重載運算符
| 可重載 | 不可重載 |
| 算術:+ - * / % ++ -- | 成員訪問:. .* :: |
| 位運算:& | ^ ~ << >> | 三目:?: |
| 邏輯:! && || | sizeof |
| 比較:== != < > <= >= | |
| 賦值:= += -= *= /= %= ^= &= |= <<= >>= | |
| 其他:[] () -> , new delete ->* | |
兩種重載形式
1. 成員函數形式
class Integer {
int val;
public:
Integer(int v=0): val(v) {}
Integer operator+(int x) const { return Integer(val + x); } // this + x
Integer& operator+=(int x) { val += x; return *this; }
Integer& operator++() { ++val; return *this; } // 前綴 ++
Integer operator++(int) { Integer t=*this; ++val; return t; } // 後綴 ++
operator int() const { return val; } // 類型轉換函數
};
- 隱含
this 指針,左操作數必須是類對象
- 適合單目運算符、修改對象狀態的運算符(=、+= 等)
2. 友元函數形式
class Integer {
int val;
friend Integer operator+(int x, const Integer& y); // 非成員,需友元訪問私有
public:
// ...
};
Integer operator+(int x, const Integer& y) { // x + y,左操作數是 int
return Integer(x + y.val);
}
- 無
this,雙目運算符兩操作數顯式傳入
- 適合雙目運算符、需隱式轉換左操作數、交換律運算符
- 必須用友元:=、[]、()、->、類型轉換函數
綜合示例:Integer 包裝類
class Integer {
int m_val;
public:
Integer(int v=0): m_val(v) {}
// 成員運算符
Integer operator+(int x) const { return Integer(m_val + x); }
Integer& operator+=(int x) { m_val += x; return *this; }
Integer& operator=(int x) { m_val = x; return *this; }
Integer& operator++() { ++m_val; return *this; }
Integer operator++(int) { Integer t(*this); ++m_val; return t; }
operator int() const { return m_val; } // 隱式轉 int
// 友元運算符(支援 1 + obj)
friend Integer operator+(int x, const Integer& y);
friend ostream& operator<<(ostream& os, const Integer& y);
};
// 友元定義
Integer operator+(int x, const Integer& y) { return Integer(x + y.m_val); }
ostream& operator<<(ostream& os, const Integer& y) { return os << y.m_val; }
使用示例
Integer a(10), b = 20; // 隱式構造
b = a + 1; // 成員 operator+
b = 1 + a; // 友元 operator+
int n = b; // 類型轉換 operator int()
b = a++; // 後綴++
b = ++a; // 前綴++
cout << b << endl; // 友元 operator<<
選擇指南:成員 vs 友元
| 場景 | 推薦形式 | 理由 |
| 單目運算符(++、--、!、~) | 成員 | 只操作 this,語義清晰 |
| 雙目運算符(+、-、*、== 等) | 友元 | 支援隱式轉換左操作數,對稱性好 |
| 賦值類(=、+=、-=) | 成員 | 修改 this 狀態,左操作數必須是對象 |
| 下標 []、調用 ()、箭頭 -> | 成員 | 語法強制要求成員 |
| 類型轉換 | 成員 | 語法強制要求成員 |
| 流輸入輸出 (<<、>>) | 友元 | 左操作數是 stream,非本類對象 |
最佳實踐原則
- 優先考慮語義直觀性,
a+b 應等價於 b+a(若符合交換律)
- 返回值:算術運算符返回值(新對象),賦值/複合賦值返回引用(
*this)
- 參數:盡量
const T&,避免拷貝
- 前綴 ++ 返回引用,後綴 ++ 返回值(需舊值副本)
- 不要重載
&&、||、,(會失去短路求值/順序點特性)