2016-11-22 131 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)); 
    
相关问题