0

Fraction クラスを作成し、その演算子の一部 (+、-、​​-、/...) をオーバーロードしようとしています。とりあえず、以下のようにしてみました。

Fraction& operator+(Fraction& rightOp)
{
    Fraction result;
    result.num = num * rightOp.den + den * rightOp.num;
    result.den = den * rightOp.den;;
    return result;
}

これは厄介な結果をもたらしました。テスト中に、使用した場合:

Fraction a(2,3);
Fraction b(4,5);
Fraction c = a + b;
cout << c << endl;

正しく印刷されます。ただし、使用した場合:

Fraction a(2,3);
Fraction b(4,5);
Fraction c;
c = a + b;
cout << c << endl;

-858993460/-858993460 と出力されます。

次に、オーバーロード関数を次のように変更しようとしたとき:

Fraction& operator+(Fraction& rightOp)
{
    Fraction* result = new Fraction;
    result->num = num * rightOp.den + den * rightOp.num;
    result->den = den * rightOp.den;
    return *result;
}

それはすべてうまくいくでしょう。これにより、C++ でクラスを指すことについて混乱しました。特定のケースで最初のクラスが失敗する理由がよくわかりません。説明をいただければ幸いです。

前もって感謝します。

注: 演算子 << は問題の原因ではありませんが、とにかくここにあります。

friend ostream& operator<<(ostream& out, Fraction& f)
{
    out << f.num << "/" << f.den << endl;
    return out;
}
4

2 に答える 2

4
Fraction& operator+(Fraction& rightOp)
{
    Fraction result;
    result.num = num * rightOp.den + den * rightOp.num;
    result.den = den * rightOp.den;;
    return result;
}

これの問題は、ローカル変数への参照を返すことです。関数の終了時にローカル変数が破棄されるため、参照は無効なオブジェクトを参照します。

代わりに使用すると、オブジェクトが動的に割り当てられるnewため、問題が解決しました。resultこのようなオブジェクトは、関数の最後で破棄されません。ただし、ここでの解決策ではないことは確かです。operator+返された参照が動的に割り当てられたオブジェクトを参照してdeleteおり、将来的に変更する必要があることは、ユーザーにはまったくわかりません。ユーザーにその負担をかけないでください。

代わりに、値で返されるように関数を変更する必要があります。

Fraction operator+(Fraction& rightOp)
{
  // ...
  return result;
}

これで のコピーが返されるので、 が関数の最後で破棄されてresultも問題ありません。result

追加のメモとして、おそらく関数が引数を取ることを望むでしょうconst Fraction&。これにより、2 番目のオペランドが右辺値 (通常は一時オブジェクト) の場合に呼び出すことができます。

于 2013-05-13T00:00:37.203 に答える