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;
}

ただし >> オーバーロード関数は無限にループしているようです。それからコアダンプ...

偶然、Ratoinal &num に "const" を追加したことがすぐにわかりました。

私の質問はなぜですか

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

コンパイルは成功するが無限ループになる?

次の結果を説明してください...ありがとう

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

int c;
const int &a=c;
cin>>a;  //pass
4

1 に答える 1

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 を受け取る 1 つの引数のコンストラクターがあると仮定すると、誤って const 引数を受け取るバージョンの operator>> は、分子と分母から暗黙的に Rational オブジェクトを作成します。その結果、無限ループが発生します。何が起こっているのかを明確にするために、上記の operator>> に Rational コンストラクター呼び出しを追加しました。

この例は、引数が 1 つのコンストラクターがある場合に、型間の自動変換を行うことの危険性を示しています。これを無効にするには、キーワード explicit を使用します。

    explicit Rational(int num);

しかし、この場合、ほとんどの場合、int から Rational への自動変換が必要になると思います。

于 2013-05-10T05:33:00.810 に答える