問題代碼片段
// 主函數中調用
cout << "2*c is " << 2 * c << endl; // 編譯錯誤:無匹配 operator*(int, Complex)
// 輸出運算符重載
friend ostream &operator <<(ostream &os, Complex &com) { // 缺少 const
os << "(" << com.real << "," << com.imag << "i)" << endl;
return os;
}
錯誤原因分析
- 乘法運算符重載缺失左操作數版本:
- 類內定義
Complex operator*(double x) 僅支持 c * 2(對象在左)。
2 * c 需要 double * Complex,屬於非成員函數(或友元函數),左操作數是內置類型 double,無法調用成員函數。
- 輸出運算符參數缺少 const:
operator<<(ostream&, Complex&) 參數非 const,導致無法輸出臨時對象(如 ~c、a+c 等表達式結果)。
- 臨時對象只能綁定到 const 引用。
修正方案
1. 添加非成員乘法運算符(支持 2 * c)
// 類外定義(或類內聲明 friend)
Complex operator*(double x, const Complex& c) {
return c * x; // 復用成員函數 c * x
}
// 或直接實現
Complex operator*(double x, const Complex& c) {
return Complex(x * c.real, x * c.imag);
}
2. 修正輸出運算符參數為 const 引用
friend ostream &operator<<(ostream &os, const Complex &com) { // 加 const
os << "(" << com.real << "," << com.imag << "i)";
return os; // 建議不自動換行,由調用者控制
}
3. 輸入運算符同理加 const(雖輸入需修改對象,但參數應為非 const 引用,此處原代碼正確)
friend istream &operator>>(istream &is, Complex &com) { // 正確:需修改 com
// ...
}
完整修正後類定義(關鍵部分)
class Complex {
double real, imag;
public:
// ... 構造函數 ...
// 成員運算符:對象在左
Complex operator+(const Complex& val) const; // 建議加 const
Complex operator-(const Complex& val) const;
Complex operator*(const Complex& val) const;
Complex operator*(double x) const; // c * 2
Complex operator~() const; // 共軛
// 友元流運算符
friend istream& operator>>(istream& is, Complex& com);
friend ostream& operator<<(ostream& os, const Complex& com); // const 關鍵
};
// 類外非成員運算符:double 在左
Complex operator*(double x, const Complex& c) {
return c * x; // 利用成員 operator*(double)
}
主函數調用驗證
Complex a(3.0, 4.0), c;
while (cin >> c) {
cout << "c is " << c << endl;
cout << "共軛: " << ~c << endl; // 臨時對象,需 const 引用
cout << "a+c: " << a + c << endl; // 臨時對象
cout << "2*c: " << 2 * c << endl; // 調用非成員 operator*(double, Complex)
// ...
}
總結
- 雙目運算符對稱性:若需支持
內置類型 * 對象,必須提供非成員函數(通常聲明為 friend)。
- 流運算符 const 正確性:
operator<< 第二參數必須為 const 引用,以支持臨時對象輸出;operator>> 第二參數為非 const 引用(需寫入)。
- 成員函數 const 資格:不修改對象的運算符(+、-、*、~、輸出)均應標記
const。