15

私はC++のいくつかのリビジョンを出していますが、私は分で演算子のオーバーロード、特に "="(代入)演算子を扱っています。私はオンラインで探していて、それについて議論している複数のトピックに出くわしました。私自身のノートでは、私はすべての私の例では、私はオンラインで見つけるすべての参照ではなぜ代入演算子はオブジェクトへの参照を返すべきですか?

​​

のようなものとして降ろさ持って、私は、オペレータがソースオブジェクトへの参照を返すことに気づきました。 オブジェクトに参照を返す正しい方法は何もないのに対して、なぜですか?

+0

正しい方法は、あなたが欲しいのセマンティクスを実装してどのような方法です。 _idiomatic_方法は確かに 'T&'(あなたの例では 'Foo&')を返すことです。 – ildjarn

+0

@MooingDuck、私は間違った言葉を書いていたと思います。私はメモが間違っていたと仮定していたが、それ以上の理由が正しいことを知りたがっていた。 – maccard

+1

[代入演算子はC++で* thisへの参照を返す可能性があります](http://stackoverflow.com/questions/5669813/assignment-operator-return-a-reference-to-this-in-c);また[代入演算子で*これを返す](0120-13753) –

答えて

17

通常の形式では、対象オブジェクトへの参照が返され、割り当ての連鎖が可能です。それ以外の場合は、行うことが可能ではないでしょう。

Foo a, b, c; 
// ... 
a = b = c; 

それでも、右assigment演算子is tougher than it might seemを取得していることに注意してください。

+0

コピーとスワップの部分については決して知りませんでした。私はいつも自分自身の割り当て、割り当てられた値、そして返された空白をチェックしただけで、私が予想していた以上にこれがあると思います。 コピー&スワップの回答を受け入れる お返事ありがとうございます。 – maccard

13

戻り値の型を使用すると、ちょうどこのような文では、単一の割り当てを実行しているときは問題ではありません:

if ((x = y)) { 

:あなたがこれを行うとき

x = y; 

それは問題を開始します。あなたがこれを行うときには本当に問題になります。

x = y = z; 

これは、現在のオブジェクトをすべて返す理由です正確な連想性を伴う割り当ての連鎖。それは良い一般的なプラクティスです。

+0

私はあなたが「それは問題になる」と言う理由を理解していません。それは問題でもなくてもかまいません。あなたは詳細を教えていただけますか? – balajeerc

+3

@balajeerc:「それは問題になる」とは、「それは後者の状況では重要だが、前者ではない」という意味で読まれる。言い換えれば、「状況AからBに変化するとき、重要性(「重要性」)はゼロから非ゼロになる」。ストレートアサインではリターンは関係ありません。条件付きの内部では、返すものが真または偽であるが、正確にどのオブジェクトではないかは重要です。連鎖割当の場合、実際には結果が直感的ではないため、現在のオブジェクトを返すようにしてください。 – Borealid

8

あなたの代入演算子は、常にこれらののことを行う必要があります。

  1. は、代入の右辺としてのconstリファレンス入力(const MyClass &rhs)してください。その理由は、その値を誤って変更したくないためです。私たちは左のものだけを変えたいと思っています。

  2. 常に新しく変更された左辺return *thisへの参照を返します。これは、オペレータの連鎖を可能にするためである。 a = b = c;

  3. 常に自己割り当て(this == &rhs)を確認してください。これは、クラスが独自のメモリ割り当てを行う場合に特に重要です。

    MyClass& MyClass::operator=(const MyClass &rhs) { 
        // Check for self-assignment! 
        if (this == &rhs) // Same object? 
         return *this; // Yes, so skip assignment, and just return *this. 
    
        ... // Deallocate, allocate new space, copy values, etc... 
    
        return *this; //Return self 
    } 
    
+1

自己割り当てを確認するのは簡単な解決策です。正しいものはコピーアンドスワップです。 –

+0

応答をありがとうが、私は自己割り当てのチェックを外して単純な例を作ることを試みていました。私は参照を返すすべてのバーを理解した。 – maccard

+0

@MatteoItaliaコピーアンドスワップは高価になる可能性があります。たとえば、ある大きなベクトルを別のベクトルに割り当てると、コピーアンドスワップが使用されている場合、ターゲットのメモリを再利用することはできません。 –

関連する問題