void Foo(int x = 0, int y = 0); // ✅ 宣告
void Foo(int x = 0, int y = 0) { ... } // ❌ 定義體中非法
原因:實作與預設值無關;預設值常變動,改宣告比改定義容易。
void Foo(int x, int y = 0, int z = 0); // ✅
void Foo(int x = 0, int y, int z = 0); // ❌ 調用時極易混淆
void output(int x);
void output(int x, float y = 0.0f); // 預設參數
output(1); // ❌ 編譯錯誤:ambiguous call
// 編譯器不知呼叫 output(int) 還是 output(int, float=0.0f)
**教訓**:預設參數僅簡化書寫,**不增加新功能**,濫用降低可讀性並引發重載二義性,**慎用**。
Complex Add(const Complex& a, const Complex& b); // 普通函數
Complex operator+(const Complex& a, const Complex& b); // 運算子多載
Complex a, b, c;
c = Add(a, b); // 普通調用
c = a + b; // 運算子調用,參數分居左右
| 形式 | 一元運算子 | 二元運算子 |
|---|---|---|
| 全域函數 | 1 參數 | 2 參數 (左、右) |
| 成員函數 | 0 參數 (隱含 *this) | 1 參數 (右側,左側為 *this) |
| 運算子類別 | 建議 |
|---|---|
| 所有一元運算子 | 成員函數 |
= () [] -> | 只能 為成員函數 |
+= -= *= /= &= |= %= >>= <<= | 成員函數 |
| 其他所有運算子 | 全域函數 (常需友元存取私有成員) |
遵循規則可保持語義直覺、介面一致、存取控制合理。