在 C++ 作業中,為 fraction(分數)類重載 operator<< 和 operator>> 是經典練習。許多初學者在實現輸入輸出運算符重載時,容易在語法細節、參數傳遞、流狀態處理上踩坑。本文針對典型錯誤代碼,逐行分析並給出修正方案。
// 類聲明片段
friend ostream& operator<<(ostream& cout, const fraction& a);
friend istream& operator>>(istream& cin, fraction& a);
// 實現文件
ostream& operator<<(ostream& cout, const fraction& a)
{
cout < return cout; // 錯誤 1:語法錯誤,缺少運算對象
}
istream& operator>>(istream& cin, fraction& a)
{
cin >> a.rn >> "/" a.dn >> endl; // 錯誤 2:字符串字面量不能直接作為提取目標
return cin;
}
operator<<cout < return cout; 中 < 後缺少右操作數。應輸出分數的具體格式,如 a.numerator << "/" << a.denominator。os 或 out 而非 cout,因該流未必是標準輸出。const fraction&,已正確。operator>>cin >> a.rn >> "/" a.dn 試圖將字符串 "/" 作為提取目標,編譯不通過。正確做法是讀取一個 char 變量暫存分隔符:char slash; cin >> a.rn >> slash >> a.dn; 並檢查 slash == '/'。is 或 in。#include <iostream>
using namespace std;
class fraction {
int num; // 分子
int den; // 分母
public:
fraction(int n = 0, int d = 1) : num(n), den(d) { normalize(); }
// 友元聲明
friend ostream& operator<<(ostream& os, const fraction& f);
friend istream& operator>>(istream& is, fraction& f);
private:
void normalize() {
if (den < 0) { num = -num; den = -den; }
int g = gcd(abs(num), den);
num /= g; den /= g;
}
static int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
};
// 輸出:格式 "num/den"
ostream& operator<<(ostream& os, const fraction& f) {
os << f.num << '/' << f.den;
return os;
}
// 輸入:期望格式 "num/den",允許前後空白
istream& operator>>(istream& is, fraction& f) {
int n, d;
char slash;
// 嘗試讀取 分子 '/' 分母
if (is >> n >> slash >> d) {
if (slash == '/' && d != 0) {
f = fraction(n, d); // 利用構造函數歸一化
} else {
is.setstate(ios::failbit); // 格式錯誤或分母為 0
}
}
// 讀取失敗時,f 保持原值,流狀態已為 failbit
return is;
}
// 測試主函數
int main() {
fraction f1(3, 4), f2;
cout << "f1 = " << f1 << endl; // 輸出: f1 = 3/4
cout << "請輸入分數 (格式: 5/6): ";
if (cin >> f2) {
cout << "f2 = " << f2 << endl;
} else {
cerr << "輸入格式錯誤!" << endl;
}
return 0;
}
cout/cin,必須使用傳入的流參數 os/is,才能支持文件流、字符串流等。n, d 實現)。iomanip 或自定義格式標志,但教學階段保持簡單即可。+、<<)常用友元或非成員函數,保持左操作數為流對象。運算符重載的核心在於保持語義直觀、參數正確、流狀態維護。輸入輸出重載更是考驗對流機制理解的試金石。掌握上述模板,配合 normalize() 等輔助邏輯,即可輕松應對分數類及類似作業。