2

私は以下の投稿を読みました。これは、移動のセマンティクスに関する非常に優れた洞察を提供します。

誰かが私に移動セマンティクスを説明できますか?

しかし、私はまだ移動セマンティクスに関する次のことを理解できていません-

  1. コピーの省略とRVOは、移動コンストラクターがなくてもクラスで機能しますか?

  2. クラスにmoveコンストラクターがない場合でも、STLコンテナーにはmoveコンストラクターがあります。のような操作のために

std :: vector vt = CreateMyClassVector();

ソートなどの操作を実行するために。STLが内部で移動セマンティクスを活用して、移動コンストラクターを必要としないコピーの省略やRVOなどの操作を使用して内部でそのような操作を改善できないのはなぜですか。

3.以下の場合、移動セマンティクスの恩恵を受けますか?

std :: vector <int> vt1(1000000、5); //値5で100万のエントリを作成して初期化します

std :: vector <int> vt2(std :: move(vt1)); //vt1をvt2に移動します

整数はプリミティブ型であるため、整数要素を移動しても利点はありません。または、ここで移動操作の後、vt2は単にヒープ内のvt1メモリを指し、vt1はnullに設定されます。実際に何が起こっているのですか?後者の場合、ポイント2でさえ、クラスのmoveコンストラクターは必要ない可能性があります。

4. std :: move on lvalueを使用してpush_back()が呼び出された場合。

    std::vector<MyClass> vt;

    for(int i=0; i<10; ++i)
    {
        vt.push_back(MyClass());
    }

    MyClass obj;

    vt.push_back(std::move(obj));

ベクトルには連続したメモリ割り当てがあり、objはメモリ内の別の場所で定義されているため、セマンティクスを移動してobjメモリをベクトルvtの連続したメモリ領域に移動します。この場合、メモリを移動するのはメモリをコピーするのと同じくらい優れていません。ヒープの異なる領域にあるメモリを指すポインタを移動するだけで、連続するメモリ要件をベクトル化します。

よろしくお願いします![要求に応じて質問を編集しました。]

4

1 に答える 1

3

ほとんどのセマンティクスは、メモリを移動する方法ではありません。あるオブジェクト インスタンスから別のオブジェクト インスタンスへのオブジェクトの所有権の移転がすべてです。これを行う場合:

std::string str1("Some string.");
std::string str2(std::move(str1));

std::string文字のバッファを割り当てて管理します。したがって、それぞれが文字列自体を含むメモリのバッファをstd::string 所有します。

construct に呼び出される move コンストラクターstr2は、によって割り当てられた文字バッファーを取得しstr1、そのオブジェクトから削除します。したがって、最初に割り当てられstr2たポインターがあり、そのポインターはもうありません。オブジェクトが所有するメモリの所有権を譲渡するのが移動セマンティクスです。str1str1

クラスにムーブ コンストラクタがない場合、std::vectorはそれを呼び出しません。明らかに。したがって、移動コンストラクターがもたらす可能性のある潜在的な最適化を利用することはできません。ただし、これらの最適化の機会は、値のセマンティクスを持ち、管理する必要があるリソースを含むオブジェクトに対してのみ存在します。そうでなければ、動きは役に立ちません。

一般的なルールは、スマート ポインターとvectorstring、 などのコンテナー オブジェクトを使用して、移動コンストラクターをまったく作成する必要がないようにすることです。したがって、(コンパイラが移動コンストラクタの生成を適切にサポートしている場合) リソース管理は自動的に行われます。

于 2013-01-30T12:29:22.507 に答える