创建对象并将其推送到向量中的正确方法是什么?

时间:2016-11-22 06:30:48

标签: c++ c++11

将对象添加到矢量的正确方法是什么?似乎一个向量需要一个对象的副本,而不是实际的对象......

例如:

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...
}

将对象放入向量中的正确方法是什么,没有副本?

4 个答案:

答案 0 :(得分:7)

如果您使用的是C ++ 11或更高版本,则可能需要使用emplace_back来创建对象:

_textures.emplace_back(textureWidth, textureHeight);

答案 1 :(得分:3)

如果您担心在插入std::vector时复制了对象,则同样可能会担心在重新分配向量时也会复制向量中已有的对象。您可以通过以下方式之一阻止该不良行为:

  1. 如果您事先知道收藏品的大小,并且可以推迟创建要插入的对象直到插入前,那么reserve() vector并使用其{ {3}}方法。

  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));
    

答案 2 :(得分:1)

使用c ++ 11,您可以为昂贵的对象提供移动构造函数:

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

因为你构造的对象是临时对象,所以它的移动构造函数将被调用。

另一种方法是调用emplace_back而不是push_back:

  _textures.emplace_back(textureWidth,textureHeight);

调用push_back将花费构造函数和移动,但emplace_back将只有一个构造函数。

然而,有时可以复制一份。如果可能,编译器将优化代码(但不要依赖它)。

答案 3 :(得分:1)

在此,您可以使用指向对象的指针向量。

{{1}}

但请记住,您必须从矢量的所有条目中取消分配内存。