運算符重載本質上是函數重載,必須遵循以下基本原則:
.、.*、::、?:、sizeof、typeid、alignof 不可重載| 運算符類別 | 推薦形式 | 強制要求 |
|---|---|---|
一元運算符 (++、--、! 等) | 成員函數 | - |
=、()、[]、->、->* | 成員函數 | 必須為成員 |
複合賦值 (+=、-= 等) | 成員函數 | - |
| 二元算術/比較/邏輯運算符 | 非成員函數 (常配合 friend) | - |
流運算符 <<、>> | 非成員 friend | 左操作數為流對象 |
class Integer {
int val;
public:
// 前置 ++i:返回引用,無額外參數
Integer& operator++() { ++val; return *this; }
// 後置 i++:int 佔位參數區分,返回舊值副本
Integer operator++(int) { Integer tmp(*this); ++val; return tmp; }
// -- 同理
};
class String {
char* data;
size_t len;
public:
String& operator=(const String& rhs) {
if (this != &rhs) { // 自賦值檢查
char* newData = new char[rhs.len + 1];
strcpy(newData, rhs.data);
delete[] data;
data = newData;
len = rhs.len;
}
return *this;
}
// C++11 移動賦值
String& operator=(String&& rhs) noexcept {
if (this != &rhs) {
delete[] data;
data = rhs.data; len = rhs.len;
rhs.data = nullptr; rhs.len = 0;
}
return *this;
}
};
template <typename T, size_t S>
class Array {
T data[S];
public:
T& operator[](size_t i) { return data[i]; }
const T& operator[](size_t i) const { return data[i]; }
};
template <typename T, size_t S>
class Array {
T data[S];
friend ostream& operator<<(ostream& os, const Array& arr) {
for (size_t i = 0; i < S; ++i) os << arr.data[i] << ' ';
return os << '\n';
}
};
return Integer(a + b); 而非構造命名變量再返回,避免拷貝構造/析構開銷explicit 禁止operator int() const { return val; } 實現對象到內置類型轉換a + b 不應修改 a 或 b== 與 !=、< 與 > 等a + b 可實現為 a += b 的副本swap 等需作為友元或非成員