2016-11-22 2 views
2

ベクトルにオブジェクトを追加する正しい方法は何ですか?例えばオブジェクトを作成してベクトルにプッシュする正しい方法は何ですか?

...ベクトルではなく実際のオブジェクトよりも、オブジェクトのコピーを取るようだ:コピーせずに、ベクトル内のオブジェクトを入れるための正しい方法である

class MyClass{ 
private: 
    std::vector<Texture>_textures; 
public: 
    void addATexture(int textureWidth,int textureHeight){ 
     Texture tex(textureWidth,textureHeight); 
     _textures.push_back(tex);//A copy of tex is pushed into in.. 
    } // ---> At this point, tex is destroyed... 
} 

何? C++ 11には、あなたは高価なオブジェクトのための移動のコンストラクタに利益をもたらすことができます使用

_textures.emplace_back(textureWidth, textureHeight); 

答えて

7

後でC++ 11またはを使用している場合は、代わりにオブジェクトを作成するemplace_backを使用することもできます。

構成するオブジェクトは一時的なものなので、移動コンストラクタが呼び出されます。

_textures.emplace_back(textureWidth,textureHeight); 

push_backは、コンストラクタや移動の費用がかかりますが、emplace_backは唯一のコンストラクタを持つことになります呼び出す:

別の方法ではなく、一backのemplace_backを呼び出すことです。

コピーを持っていてもかまいません。可能であれば、コンパイラはコードを最適化します(ただし、依存しないでください)。

1

+2

コピーに副作用がある場合、それは省略されません。 – Danh

1

ここでは、オブジェクトへのポインタのベクトルを使用できます。

class MyClass{ 
private: 
    std::vector<Texture *> _textures; 
public: 
    void addATexture(int textureWidth,int textureHeight){ 
     Texture * tex = new Texture(textureWidth,textureHeight); 
     _textures.push_back(tex);`enter code here` 
    } 
} 

しかし、あなたは、ベクトルのすべてのエントリからメモリを割り当て解除する必要があります覚えておいてください。

+0

ベクトルがオブジェクトを所有することになっている場合は、スマートポインタのベクトル( 'std :: unique_ptr'または' std :: shared_ptr')を使う方がよい。 –

3

std::vectorにオブジェクトを挿入したときにオブジェクトがコピーされることに懸念がある場合は、同様に、ベクターが再割り当てされたときに既にベクター内にあるオブジェクトもコピーされることが懸念されます。次のいずれかの方法で、その望ましくない動作を防ぐことができます。

  1. あなたが事前にあなたのコレクションのサイズを知っていて、右の前に挿入まで挿入するオブジェクトの作成を延期することができた場合は、reserve()vectorを使用し、そのemplace_back()メソッドを使用します。

  2. そうでない場合は、あなたのクラスは移動コンストラクタと移動-代入演算子(すなわち、適切な移動-代入演算子または値によって、その引数を取る代入演算子)と同等のものを提供していることを確認します。

    // CAVEAT: this will compile even if Texture is not a movable type (as long 
    // CAVEAT: as it is copyable) 
    std::vector<Texture> _textures; 
    Texture tex(textureWidth,textureHeight); 
    _textures.push_back(std::move(tex)); 
    //     ^^^^^^^^^ 
    
  3. または(std::unique_ptrを通じて、または、より良い)つまり、ポインタを通じて、間接的にstd::vectorであなたのオブジェクトを格納:

    std::vector<std::unique_ptr<Texture>> _textures; 
    _textures.push_back(std::make_unique<Texture>(textureWidth,textureHeight)); 
    
関連する問題