move
の後に、オブジェクトは新しいものと古いものの間に依存関係がありますか?int main () {
int a = 100;
std::cout<<&a<<std::endl;
auto a_copy = a; // deduced as int
std::cout<<&a_copy<<std::endl;
auto a_move = std::move(a); // deduced as int
std::cout<<&a_move<<std::endl;
};
出力:
0x7fffffffe094
0x7fffffffe098
0x7fffffffe09c
thisの例では、違いはありません。最終的には、値が100の3つのint
sになります。ただし、タイプによっては間違いなく違いがある可能性があります。たとえば、vector<int>
のようなものを考えてみましょう:
std::vector<int> a = {1, 2, 3, 4, 5}; // a has size 5
auto a_copy = a; // copy a. now we have two vectors of size 5
auto a_move = std::move(a); // *move* a into a_move
最後の変数a_move
は、a
の内部ポインターの所有権を取得します。つまり、a_move
はサイズ5のベクトルですが、a
は空になっています。 move
はcopy
よりもはるかに効率的です(代わりに1000文字列のベクトルである場合を想像してください。a_copy
は1000文字列バッファの割り当てと1000文字列のコピーを含みますが、 a_move
は、いくつかのポインタを割り当てるだけです)。
他のいくつかのタイプでは、1つが無効である可能性があります。
std::unique_ptr<int> a{new int 42};
auto a_copy = a; // error
auto a_move = std::move(a); // OK, now a_move owns 42, but a points to nothing
ただし、多くのタイプで違いはありません。
std::array<int, 100> a;
auto a_copy = a; // copy 100 ints
auto a_move = std::move(a); // also copy 100 ints, no special move ctor
より一般的には:
T a;
auto a_copy = a; // calls T(const T& ), the copy constructor
auto a_move = std::move(a); // calls T(T&& ), the move constructor
std::move
を使用すると、左辺値がx値に変更されるだけなので、移動コンストラクターおよび移動代入演算子で使用できます。これらは組み込み型には存在しないため、この例ではmoveを使用しても違いはありません。
その例のデフォルトのコピーとstd :: moveの違いは何ですか?
違いはありません。何かをコピーすると、移動の要件が満たされます。組み込み型の場合、移動はコピーとして実装されます。
オブジェクトを移動した後、新旧の間に依存関係があります
いいえ、依存関係はありません。両方の変数は独立しています。
他の投稿者の答えを拡張するために、次の例のように、MOVE IS A COPYパラダイムは、PODタイプで構成される(またはPODタイプで構成される他のタイプで構成される)すべてのデータ構造にも適用されます。
_struct Foo
{
int values[100];
bool flagA;
bool flagB;
};
struct Bar
{
Foo foo1;
Foo foo2;
};
int main()
{
Foo f;
Foo fCopy = std::move(f);
Bar b;
Bar bCopy = std::move(b);
return 0;
}
_
Foo
とBar
の両方の場合、どちらも最終的にはPODタイプの集合体であるため、データを別のデータに移動する意味のある方法はありません。それらのデータは間接的に所有されません(を指すまたは他のメモリを参照します)。したがって、これらの場合、移動はコピーとして実装され、元の(f
、b
)は、std::move()
行の割り当て後も変更されないままです。
移動セマンティクスは、動的に割り当てられたメモリまたは一意のリソースでのみ意味のある方法で実装できます。