简体   繁体   中英

What is the correct way to create an object and push it in a vector?

What is the correct way to add an object to a vector ? It seems that a vector takes a copy of the object, rather than the actual object...

For example:

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

What is the correct way to put objects in the vector, without copies ?

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

_textures.emplace_back(textureWidth, textureHeight);

If you are concerned that your object is copied when inserted into a std::vector , you may likewise be concerned that objects that are already in the vector are also copied when the vector is reallocated. You can prevent that undesired behavior in one of the following ways:

  1. If you know the size of your collection beforehand and can postpone the creation of the object to be-inserted till right-before-insertion, then reserve() the vector and use its emplace_back() method.

  2. Otherwise, ensure that your class provides a move constructor and an equivalent of a move-assignment operator (ie a proper move-assignment operator or an assignment operator that takes its argument by value):

     // 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. Or store your objects in std::vector indirectly, ie through pointers (or, better, through std::unique_ptr ):

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

Using c++11, you can benefit move constructor for costly objects:

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

Because the object you construct is a temporary one, it's move constructor will be called.

Another way is to call emplace_back instead of push_back:

  _textures.emplace_back(textureWidth,textureHeight);

Calling push_back will cost a constructor and a move, but emplace_back will have only one constructor.

However, sometimes it's OK to have a copy. Compiler will optimize out the code if possible (But don't rely on it).

In this you can use vector of pointer to the object.

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

But remember you will have to de-allocate memory from all the entries of the vector.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM