2

たとえば、次の移動コンストラクターは&&(rvalue 参照)なしで機能します。

Obj::Obj(Obj& obj) : elem { obj.elem }, data(obj.data) {

    obj.elem = nullptr;
    obj.data = 0;

}

なぜ必要なのかがよくわかりません…

4

2 に答える 2

14

右辺値参照引数は、右辺値以外の参照へのバインドを拒否します。この制限により、move操作は、移動元のオブジェクトが後でコード内で明示的に参照できない場合 (一時的に破棄されるか、ローカル変数が返されるため)、または呼び出し元が明示的にmovedを実行したためにのみ発生します。それらから。

これが必要な理由を確認するには、 の履歴を調べるか、タイプauto_ptrを使用する次の例を読んでください。Obj

int main() {
  Obj a;
  Obj b = a; // oops!  You just *moved* a into b!
}

適切なmoveコンストラクターを使用すると、右側がコンパイラーが検出できる方法ですぐに破棄される値である場合、または を呼び出す場合にのみ呼び出されますmove

その上、&参照は一時変数へのバインドを拒否します。一時変数は aconst&または aにのみバインドでき&&ます。

于 2013-08-09T13:38:46.563 に答える
12

あなたの例は一時的にバインドできないため、これらは機能しません:

Obj makeObj() { return Obj(); }

Obj o1(Obj());     // Error
Obj o2(makeObj()); // Error

さらに、コピー元のオブジェクトから状態を盗むコピー コンストラクターが本質的にあるため、物事を壊すのが非常に簡単になります。

Obj o1;
Obj o2{o1}; // o1 is modified
于 2013-08-09T13:38:29.057 に答える