2013-05-10 86 views
2

我爲我的大學作業寫了一個理性的類。>>操作符重載函數無限遞歸

class Rational 
{ 
    friend std::istream &operator >>(std::istream &, const Rational &); 
    friend std::ostream &operator <<(std::ostream &, const Rational &); 
public: 
    ... 
private: 
    int numerator; 
    int denominator; 
} 

istream &operator >>(istream &istm, const Rational &num){ 
    istm>>num.numerator>>num.denominator; 
    return istm; 
} 

但是>>重載函數似乎循環無限。然後核心轉儲...

我很快發現我已經添加了「const」給Ratoinal & num意外。

我的問題是,爲什麼

istm>>num.numerator>>num.denominator; 

編譯成功,但成爲一個無限循環?

,並請解釋以下結果......感謝

const int i; 
cin>>i; //compile error 

int c; 
const int &a=c; 
cin>>a; //pass 
+0

你確定它是一個無限循環?還是隻是在終端等待輸入'istream'? – Yuushi 2013-05-10 05:26:00

+0

對於第二個問題,您可以嘗試刪除您的'operator >>'重載,並查閱john的答案以獲取更多信息。 – Nbr44 2013-05-10 05:39:36

+0

對不起蒂姆,但你所描述的只是不可能與所示的代碼。請嘗試編寫和發佈一些代碼來重現問題。你會看到上述兩種情況都會產生編譯錯誤。也許你的「症狀」來自其他原因,比如在你誤認爲一個成功的編譯失敗等錯誤後,運行一個過時的二進制文件和其他一些錯誤。無論如何,我建議關閉它作爲「不是一個真正的問題」...... – 2013-05-10 05:58:10

回答

3

您還沒有表現出所有類的,但我猜想,以下是發生

class Rational 
{ 
    friend std::istream& operator>>(std::istream&, const Rational&); 
    friend std::ostream& operator<<(std::ostream&, const Rational&); 
public: 
    Rational(int num); 
    ... 
private: 
    int numerator; 
    int denominator; 
}; 

istream& operator>>(istream& istm, const Rational& num) 
{ 
    istm >> Rational(num.numerator) >> Rational(num.denominator); 
    return istm; 
} 

假設您的Rational類有一個一個參數的構造函數接受一個int,那麼你的operator >>版本,錯誤地接受一個const參數,將隱式地從分子和分母創建Rational對象。結果無限循環。我已經將Rational構造函數調用添加到上面的運算符中,以清楚地說明發生了什麼。

這個例子顯示了當你有一個參數構造函數時,在類型之間進行自動轉換的危險。您可以使用關鍵字explicit將其禁用。

explicit Rational(int num); 

,但我想在這種情況下,你可能想要自動轉換從int到理性的大部分時間。

+0

這實際上也回答了他的第二個問題:) – Nbr44 2013-05-10 05:38:40

+0

我認爲這是正確答案,但我不希望Rational(int)是明確的。聲明這樣工作:「cout <<(1/Rational(1,3));」,它產生3 – 2013-05-10 07:07:24

+0

@ Nbr44他真的回答我的第二個問題嗎? 但是..我沒有看到任何重載函數以const int&爲參數http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ – 2013-05-10 07:13:51