<< / >>?C++ 標準庫已為內建型別(int、double、string 等)重載串流運算符。但自定義類型若要支援 cout << obj、cin >> obj 這種直觀語法,必須自行重載。目標是讓自訂類型擁有與內建型別一致的 I/O 體驗。
因為左操作數是串流物件(ostream/istream),無法作為成員函數(那需要修改標準庫類)。因此只能以全域函數(通常聲明為友元)重載。
operator<<ostream& operator<<(ostream& out, const Complex& c) {
out << c.m_real << " + " << c.m_imag << " i";
return out; // 返回引用支援鏈式輸出
}
ostream&(輸出串流引用)const Complex&(常量引用,不修改物件)ostream&,實現 cout << a << bfriend 以訪問 private 成員operator>>istream& operator>>(istream& in, Complex& c) {
in >> c.m_real >> c.m_imag;
return in; // 返回引用支援鏈式輸入
}
Complex&(非常量引用,需修改物件)istream&,實現 cin >> a >> bfriend#include <iostream>
using namespace std;
class Complex {
public:
Complex() : m_real(0), m_imag(0) {}
Complex(double r, double i) : m_real(r), m_imag(i) {}
// 算術運算符重載(全域友元)
friend Complex operator+(const Complex&, const Complex&);
friend Complex operator-(const Complex&, const Complex&);
friend Complex operator*(const Complex&, const Complex&);
friend Complex operator/(const Complex&, const Complex&);
// I/O 運算符重載(全域友元)
friend istream& operator>>(istream&, Complex&);
friend ostream& operator<<(ostream&, const Complex&);
private:
double m_real, m_imag;
};
// I/O 實現
istream& operator>>(istream& in, Complex& c) {
in >> c.m_real >> c.m_imag;
return in;
}
ostream& operator<<(ostream& out, const Complex& c) {
out << c.m_real << " + " << c.m_imag << " i";
return out;
}
// 算術實現略...
int main() {
Complex c1, c2, c3;
cin >> c1 >> c2; // 輸入: 2.4 3.6 4.8 1.7
c3 = c1 + c2; cout << "c1 + c2 = " << c3 << endl;
c3 = c1 - c2; cout << "c1 - c2 = " << c3 << endl;
c3 = c1 * c2; cout << "c1 * c2 = " << c3 << endl;
c3 = c1 / c2; cout << "c1 / c2 = " << c3 << endl;
}
2.4 3.6 4.8 1.7 c1 + c2 = 7.2 + 5.3 i c1 - c2 = -2.4 + 1.9 i c1 * c2 = 5.4 + 21.36 i c1 / c2 = 0.942308 + 0.705128 i
| 項目 | operator>> | operator<< |
|---|---|---|
| 第一參數 | istream& | ostream& |
| 第二參數 | Type& (可修改) | const Type& (唯讀) |
| 返回型別 | istream& | ostream& |
| 鏈式調用 | cin >> a >> b | cout << a << b |
| 友元聲明 | 必要 (訪問 private) | 必要 (訪問 private) |
iomanip 格式化,輸入時處理空白、分隔符in.fail(),異常輸入時保持物件有效ios::fmtflags 保存/恢復重載 <</>> 讓自定義類型融入 C++ 串流生態,實現與內建型別一致的 I/O 體驗。核心在於:全域函數、友元聲明、引用參數、引用返回、const 正確性。這是構建專業級 C++ 類庫的基礎技能之一。