この「移動」セマンティックの目的は何ですか? 参照によって渡さない場合、コピーが非プリミティブ型で作成されていることは理解していますが、「移動」によって何かがどのように変化するのでしょうか? なぜデータを「移動」したいのでしょうか? 同じアドレスに保管して、コピーしないでください。別のアドレスに送信された場合、これは単なる「コピーして削除」ではありませんか?
要するに、移動のセマンティクスが正確に何を達成しているのか、私にはよくわかりません。
この「移動」セマンティックの目的は何ですか? 参照によって渡さない場合、コピーが非プリミティブ型で作成されていることは理解していますが、「移動」によって何かがどのように変化するのでしょうか? なぜデータを「移動」したいのでしょうか? 同じアドレスに保管して、コピーしないでください。別のアドレスに送信された場合、これは単なる「コピーして削除」ではありませんか?
要するに、移動のセマンティクスが正確に何を達成しているのか、私にはよくわかりません。
Move セマンティクスは、値渡しと参照渡しの利点を組み合わせたものです。クラスを静的に割り当てるため、クラスの有効期間に責任を負う必要がなく、パラメーターとして渡して関数から簡単に返すことができます。一方、通常であればオブジェクトがコピーされているはずのオブジェクトが移動されます (内部のみがコピーされます)。この操作は、コピーよりもはるかに少ない時間コストで実装できます (rhs オブジェクトはもう使用されないことがわかっているため)。
MyObj * f()
{
// Ok, but caller has to take care of
// freeing the result
return new MyObj();
}
MyObj f()
{
// Assuming, that MyObj does not have move-ctor
// This may be time-costly
MyObj result;
return result;
}
MyObj f()
{
// This is both fast and safe
MyObj result;
return std::move(result);
// Note, if MyObj implements a move-ctor,
// usually you don't have to call std::move.
}
同じアドレスに保管してコピーしないでください。
これは実際にムーブ セマンティクスが一般的に行っていることです。多くの場合、リソース (多くの場合はメモリですが、ファイル ハンドルなどの場合もあります) をまったく同じ状態に保ちますが、オブジェクト内の参照を更新します。
2 つのベクトル と を想像してsrc
くださいdest
。src
ベクターには、ヒープに割り当てられたdest
空の大きなデータ ブロックが含まれています。src
が移動すると、ヒープ上のメモリのブロックを指すように更新されdest
ますが、指していたものは何でも、この場合は何も指すように更新されます。dest
src
dest
なぜこれが役立つのですか?vector
これは、 1 つのベクトルのみが割り当てられたメモリ ブロックを指すという確信を持って記述できることを意味するためです。これは、デストラクタが、割り当てられたメモリを確実にクリーンアップできることを意味します。
これは、ファイル ハンドルなど、他のリソースを管理するオブジェクトに拡張できます。ファイル ハンドルを所有できるオブジェクトを記述できるようになりました。これらのオブジェクトは移動できますが、コピーはできません。STL コンテナは可動オブジェクトをサポートしているため、C++03 よりもはるかに簡単にこれらをコンテナに配置できます。それらのファイル ハンドル、またはその他のリソースは、それへの参照のみを持つことが保証され、デストラクタは適切に閉じることができます。