たとえば、次の移動コンストラクターは&&
(rvalue 参照)なしで機能します。
Obj::Obj(Obj& obj) : elem { obj.elem }, data(obj.data) {
obj.elem = nullptr;
obj.data = 0;
}
なぜ必要なのかがよくわかりません…
たとえば、次の移動コンストラクターは&&
(rvalue 参照)なしで機能します。
Obj::Obj(Obj& obj) : elem { obj.elem }, data(obj.data) {
obj.elem = nullptr;
obj.data = 0;
}
なぜ必要なのかがよくわかりません…
右辺値参照引数は、右辺値以外の参照へのバインドを拒否します。この制限により、move
操作は、移動元のオブジェクトが後でコード内で明示的に参照できない場合 (一時的に破棄されるか、ローカル変数が返されるため)、または呼び出し元が明示的にmove
dを実行したためにのみ発生します。それらから。
これが必要な理由を確認するには、 の履歴を調べるか、タイプauto_ptr
を使用する次の例を読んでください。Obj
int main() {
Obj a;
Obj b = a; // oops! You just *moved* a into b!
}
適切なmove
コンストラクターを使用すると、右側がコンパイラーが検出できる方法ですぐに破棄される値である場合、または を呼び出す場合にのみ呼び出されますmove
。
その上、&
参照は一時変数へのバインドを拒否します。一時変数は aconst&
または aにのみバインドでき&&
ます。
あなたの例は一時的にバインドできないため、これらは機能しません:
Obj makeObj() { return Obj(); }
Obj o1(Obj()); // Error
Obj o2(makeObj()); // Error
さらに、コピー元のオブジェクトから状態を盗むコピー コンストラクターが本質的にあるため、物事を壊すのが非常に簡単になります。
Obj o1;
Obj o2{o1}; // o1 is modified