2

最近分数クラスを作成していますが、演算子をオーバーロードすると意図した結果が得られません。その理由はわかりません。誰かが光を当てるのを手伝ってくれることを願っています。関連するコードのみを含めようとしました。

const fraction fraction::operator* (fraction frac)
{
    return fraction(frac.numerator * numerator, frac.denominator * denominator);
}

const fraction fraction::operator* (int num)
{
    return fraction(numerator*num, denominator);
}

fraction& fraction::operator= (const fraction &rightSide)
{
    return *this;
}

これらの操作は、正しく機能していることがわかったものです (frac# は小数オブジェクトです)。

frac1 = frac2;
frac3 = frac4 * 2;
frac5 = frac6 * frac7;

上記の操作は期待どおりに機能しますが、次の操作では frac8 が初期化されたままになります。

fraction frac8(4, 5); // Initializes a fraction, setting numerator = 4, denominator = 5
frac8 = frac8 * 3; // This doesn't quite work, leaving frac8 with the original numerator/denominator

frac3 = frac4 * 2 が機能するのに frac8 = frac8 * 3 が機能しない理由がよくわかりません。何か案は?代入演算子で const キーワードを使用すると、解決策ではないことがわかりました。

4

3 に答える 3

5

operator=本体で を実行するだけで、何か有用なことを行うとどのように期待できますreturn *this;か? thisのフィールドのフィールドに割り当てる必要がありますrightSide

しかし、もっと重要なことは、コピーの場合に特定の処理が必要なリソースをクラスが管理していない場合は、コンパイラが提供する代入演算子を使用するだけで済むということです。あるインスタンスのフィールドを別のインスタンスにコピーするだけで、fractionクラスにとってはまったく問題ないように見えます。

ところで、通常は、対応する複合演算子を使用して「通常の」演算子を実装します。演算子のオーバーロードに関する FAQをご覧になることをお勧めします。

于 2012-08-21T22:12:16.553 に答える
1

割り当て演算子の実装は空であり、左側への参照を返す以外に何もしないため、割り当てはどれも機能しません。

つまり、これら 3 つの課題のいずれも

frac1 = frac2;
frac3 = frac4 * 2;
frac5 = frac6 * frac7;

本当にうまくいきます。

何らかの理由で、上記の割り当てが「機能する」と主張していますが、それはあなたの側で何らかの混乱を引き起こしているに違いありません。それらは「機能しません」。frac8 = frac8 * 3まったく同じ理由で、どちらもありません。

PSあなたの「働く」声明は実際にはこのように書かれていると思います

fraction frac1 = frac2;
fraction frac3 = frac4 * 2;
fraction frac5 = frac6 * frac7;

これは確かにうまくいくかもしれません。しかし、この構文は代入演算子とは何の関係もありません。このような場合、代入演算子は使用されません。この構文はcopy-initializationに対応します。代入演算子ではなく、クラスのコピー コンストラクターに (少なくとも概念的には) 依存しています。これが機能する可能性がある理由ですが、コピー代入演算子を空にして「無力化」したため、真の代入は機能しません。

于 2012-08-21T22:37:32.797 に答える
0

あなたの代入演算子は、オブジェクト自体(つまり、*this)のみを返しています...したがって、最後の例では、右側のオブジェクトから実際の代入操作を実行するのではなく、単に何もしません。つまり、一時fractionオブジェクトは によって作成されますoperator*が、代入演算子は右側のオブジェクトの値をコピーしないため、メソッドの完了後にfractionによって生成された一時インスタンスを単純に破棄することになります。operator*operator=

ところで、ユーザー生成の代入演算子の作成に関しては、3 つのルールを検討することをお勧めします。基本的に、クラスにユーザー生成の代入演算子を必要とするリソースがある場合、ユーザー定義のコピーコンストラクターとデストラクタも実装する必要があると述べています...後者の2つの項目のコンパイラ生成のデフォルトはそうではありませんこれらのメソッドのコンパイラのデフォルト実装で実装されるものを超えて管理する必要があるリソースがある場合は、これで十分です。

于 2012-08-21T22:12:39.017 に答える