9

多数のPODメンバーがいるクラスを効率的に移動するにはどうすればよいですか?例:

struct{
    int a1;
    int a2;
    int a3;
    ...
    ...
    ...
};

'move'とは、動作がmoveセマンティクス(std :: move)に似ていることを意味します。

4

4 に答える 4

16

PODは移動せず、コピーするだけです。間接参照がないからです。したがって、通常の割り当てを使用し、コンパイラーに、考えている効率に合わせて最適化するように依頼してください。体系的に、前(地球上であなたが異なって行っていること)と後を測定することを忘れないでください。また、無駄なプログラマーの時間、つまりお金が、マイクロ最適化の価値があるかどうかも検討してください。

于 2012-07-21T02:39:12.747 に答える
14

この質問は、C++11 での移動の目的を理解していないことを示しています。

ポインターを持っているか、リソースを所有しているオブジェクトをコピーする場合、そのコピーを行うには 2 つの方法があります。ポインター/リソース参照をコピーするか、新しいオブジェクト/リソースを割り当てて元の値を新しいオブジェクトにコピーすることができます。

最初のケースでは、同じオブジェクトへの参照を持つ 2 つのオブジェクトが残ります。Qt はこれを頻繁に行います。1 つのオブジェクトを使用してそれが参照するものを変更すると、他のオブジェクトも変更されます。通常、ポインターを二重に削除したり、リソースを二重に解放したりしないようにするには、ある種の参照カウンターが必要です。

2 番目のケースでは、2 つの完全に別個のオブジェクトが残ります。これは一般に「値セマンティクス」と呼ばれます。1 つの POD を別の POD にコピーすると、後で 2 つの完全に別個のオブジェクトが作成されるためです。1 つを変更しても、別のものは変更されません。

移動セマンティクスは、通常は値セマンティクスを持つオブジェクトが特定の条件下で参照セマンティクスを持つことを可能にする C++11 メカニズムです。基本的に、オブジェクトが別のオブジェクトインスタンスによって参照されるポインター/リソースを盗むことを可能にします。

たとえばstd::vector、これは、動的に割り当てられ、サイズ変更された配列の単なるラッパーです。ほとんどの C++ 標準ライブラリ オブジェクトと同様に、vector値のセマンティクスを実装します。をコピーする場合vector、新しいベクトルは新しい配列を割り当て、各要素を古いものから新しいものにコピーする必要があります。完了すると、2 つの完全に別個のアレイが作成されます。

移動セマンティクスは、内に含まれる配列を別の配列vectorに転送する方法です。操作後、移動元オブジェクトは「空」になります (技術的には未定義の状態ですが、割り当てたデータから効果的に分離されます)。新しいvectorものには、古いものとまったく同じポインターが含まれるようになりましvectorた。newvectorは、割り当てられなかったメモリを削除します。

ご覧のとおり、これはすべてリソースを所有するオブジェクトの概念に基づいています。vector配列を割り当てて所有します。そのデストラクタはそれを破壊します。それが所有権を定義する方法です。移動とは、所有権を譲渡することです。

POD は単純なデストラクタ (つまり、何もしないデストラクタ) を持つ必要があるため、POD はポインタまたはリソースの所有権を表すことができません。POD は所有権を表すことができないため、移動するものはありません。オブジェクトが何も所有していない場合、オブジェクト間で所有権を譲渡することはできません。

于 2012-07-21T03:58:10.413 に答える
8

エンジニアリングの判断を働かせる必要があります。std::array<int, N>a を使用するか、アイテムで a を使用するかについて話している例を想像してみてください。ここstd::vector<int>で、はコンパイル時の定数です。NN

Nが非常に小さい場合std::array<int, N>は、ヒープ割り当てがないため明らかに勝者です。そして、コピー (およびコピーに相当する移動) は安価です。

Nが非常に大きい場合はstd::vector<int>、明らかに勝者です。なぜなら、ヒープの割り当てがありますがvector、 のサイズに関係なく、3 単語を移動するだけのコストで を移動できるからですN

の場合N == 3、どちらがより良い選択であるかは疑いの余地がありません。N == 3,000,000どちらがより良い選択であるかに疑いの余地がないとき。

デザイナーとしてのあなたの仕事は、これら 2 つの両極端の間の灰色の領域に足を踏み入れ、正しい決定を下すことです。常に正しい決定はありません。予想されるユース ケースに対するパフォーマンス測定は大いに役立ちます。<chrono>これらのパフォーマンス測定に使用します。わからない場合<chrono>は、stackoverflow で検索してください。

于 2012-07-21T03:03:56.280 に答える
2

POD を持つクラスを指すクラスを作成し、前者で std::move を使用します。

于 2012-07-21T04:03:24.497 に答える