運算符重載讓自定義類型像內置類型一樣自然使用。C++98/11/17 規定相同,大多數運算符可重載,少數不可。
| 可重載 | 不可重載 |
|---|---|
| + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= <<= >>= == != <= >= && || ++ -- , ->* -> () [] new delete new[] delete[] | :: (作用域) . (成員訪問) .* (成員指針訪問) ?: (三目) sizeof alignof typeid |
注意:.、.*、::、?: 語法內建,不可重載。->、()、[]、= 必須作為成員函數重載;其餘可作為友元或普通函數。
class Integer {
int val;
public:
Integer(int v=0): val(v) {}
// 算術
Integer operator+() const { return *this; }
Integer operator-() const { return Integer(-val); }
Integer operator+(const Integer& r) const { return Integer(val + r.val); }
// ... -, *, /, % 同理
// 自增自減
Integer& operator++() { ++val; return *this; } // 前置
Integer operator++(int) { Integer t=*this; ++val; return t; } // 後置
// 比較
bool operator==(const Integer& r) const { return val == r.val; }
bool operator<(const Integer& r) const { return val < r.val; }
// ... >, !=, <=, >= 可用 == 和 < 合成
// 位運算
Integer operator~() const { return Integer(~val); }
Integer operator<<(int n) const { return Integer(val << n); }
// ... >>, &, |, ^ 同理
// 賦值與復合賦值
Integer& operator=(const Integer& r) { val = r.val; return *this; }
Integer& operator+=(const Integer& r) { val += r.val; return *this; }
// ... -=, *=, /=, %=, &=, |=, ^=, <<=, >>= 同理
// 轉換函數
operator int() const { return val; }
};
templateclass Pointer { T* ptr; public: Pointer(T* p=0): ptr(p) {} T& operator*() const { return *ptr; } T* operator->() const { return ptr; } T& operator[](int i) const { return ptr[i]; } Pointer& operator++() { ++ptr; return *this; } Pointer operator++(int) { Pointer t=*this; ++ptr; return t; } Pointer& operator+=(int n) { ptr += n; return *this; } Pointer operator+(int n) const { return Pointer(ptr + n); } // ... -, -= 同理 };
若提供 void* operator new(size_t, Args...),必須提供對應 void operator delete(void*, Args...),否則構造函數拋異常時內存洩漏。並用基類 StandardNewDeleteForms 保留標準 new/delete 避免被遮蔽。
運算符重載核心是「保持直觀語義」。遵循標準庫慣例(如流輸出 operator<<、比較 operator<、智能指針 operator*/->),代碼才易讀、易維護。