2013-05-10 78 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