2016-11-22 45 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... 
} 

什麼是擺在矢量對象的正確方法,沒有副本?

回答

7

如果您正在使用C++ 11或更高版本,您可能需要使用emplace_back創建到位對象:

_textures.emplace_back(textureWidth, textureHeight); 
1

使用C++ 11,你可以受益於昂貴的對象移動的構造函數:

_textures.push_back(Texture(textureWidth,textureHeight)); 

因爲您構建的對象是臨時對象,所以它的移動構造函數將被調用。

另一種方法是調用emplace_back代替的push_back的:

_textures.emplace_back(textureWidth,textureHeight); 

調用push_back將花費一個構造函數和一個舉動,卻emplace_back將只有一個構造函數。

但是,有時可以有副本。如果可能的話,編譯器會優化代碼(但不要依賴它)。

+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::vector你的對象間接地,即通過指針(或更好,通過std::unique_ptr):

    std::vector<std::unique_ptr<Texture>> _textures; 
    _textures.push_back(std::make_unique<Texture>(textureWidth,textureHeight)); 
    
相關問題