5

次のコードを見てください。

#include <iostream>
using namespace std;

class Widet{
public:
    Widet(int val = 0):value(val)
    {

    }

    Widet& operator=(Widet &rhs)
    {
        value = rhs.value;
        return *this;
    }
    int getValue()
    {
        return value;
    }
private:
    int value;
};

int main()
{
    Widet obj1(1);
    Widet obj2(2);
    Widet obj3(0);
    (obj3 = obj2) = obj1;
    cout << "obj3 = " << obj3.getValue() << endl;
}

コードは正常に実行され、出力は(VS2008を使用して)次のようになります。

ここに画像の説明を入力してください

operator =に参照の代わりに値を返させると、次のようになります。

Widet operator=(Widet &rhs)
{
    value = rhs.value;
    return *this;
}

また、正常に実行され、出力は次のとおりです。

ここに画像の説明を入力してください

私の質問は:なぜ2番目のコードがうまく実行されるのですか?エラーが発生しないのですか?

*thisではなく*thisへの参照を返すのが良い習慣であるのはなぜですか?

4

7 に答える 7

8

2 番目のコードがうまく動作するのはなぜですか?エラーが発生するのではないでしょうか?

それは完全に有効なコードだからです。オブジェクトの一時コピーを返し、一時オブジェクトでメンバー関数 ( を含むoperator=()) を呼び出すことができるため、エラーは発生しません。

オブジェクトがコピーできない場合、エラーが発生します。

*this ではなく *this への参照を返すのが良い習慣なのはなぜですか?

すべてのオブジェクトがコピー可能であるとは限らず、一部のオブジェクトはコピーにコストがかかるためです。任意のオブジェクトへの参照を取得でき、参照は常に低コストで受け渡しできます。

于 2012-08-20T13:32:28.113 に答える
3

=通常、演算子をl値として使用できるように、参照を返します。

于 2012-08-20T13:24:52.573 に答える
3

参照を返さない場合(obj3 = obj2)は、 の一時的なコピーを提供しますobj3。コピーは から値を取得してobj1削除されますobje3が、2 番目の割り当ての影響を受けることはありません。

于 2012-08-20T13:31:36.910 に答える
2

2 番目のコードがうまく動作するのはなぜですか?エラーが発生するのではないでしょうか?

非constメンバー関数は(非const)クラスの右辺値でも呼び出すことができるため、実行されます。の 2 番目のバージョンはoperator=非 const クラスの右辺値を返すため、実際にはobj3変数に以前の値を残して一時に代入します。

したがって、エラーはありません。

于 2012-08-20T13:31:29.730 に答える
0

2 番目の例では、一時 (operator= によって返される Obj3 のコピー) を作成し、それに Obj1 を割り当てます。その後、すぐに破壊されます。Obj3 は、最初の代入の結果のままです - Obj3 = Obj2

于 2012-08-20T13:29:34.693 に答える
0
(obj3 = obj2)

obj3operator=(obj2)//仮説として考えることができます。
obj2 をパラメーターとして渡したので、オペレーター オーバーロードは obj2.value を obj3.value にコピーします。

(obj3 = obj2) = obj1;
from が戻った後operator=obj3 (*this,temporary copy) が返されます。
したがって、同等のコードは、obj3=obj1再び of を呼び出しoperator=、 of の値をieobj3にリセットします。obj3.valueobj1.value1

于 2012-08-20T13:36:48.750 に答える
0

operator=() から参照を返すと、次のような式が可能になります。

a=b=c;

必要のないときに値を返すのは過剰かもしれません。余分なコピー コンストラクター/デストラクター呼び出しが発生する可能性があります。それ以外の場合、値を返すことは完全に有効な C++ です。人々、私が間違っている場合は修正してください。ただし、移動セマンティクスのために、C++ 11 では値による戻りはそれほど大きな問題ではないと思います。

于 2012-08-20T13:30:23.510 に答える