When adding an element to a vector, how to know that a copy of the object is going to be made?

浪子不回头ぞ 提交于 2019-12-11 08:20:00

问题


I have an object called LastQueryInfo lastQuery in my class. Every time this object changes, I add it to a vector called history.

Initially, when I did history.push_back(lastQuery) I didn't know what would happen - is the vector going to make a copy of the object? or is it going to keep a reference to it? So if later I modify lastQuery, are all the objects (assuming they are references) in the history vector going to be modified?

After some testing, I found that history.push_back(lastQuery) is indeed going to make a copy of the object, then add it to the vector. But how can I know that without doing any tests? How can I know when C++ is going to make a copy, and when it's going to add the actual object?


回答1:


std::vector always stores a copy of whatever you push_back(). So modifying the value you passed in will not affect the value stored in the vector. It isn't like Java or C# where an Object o; is actually a reference to the object, and the object lives until the garbage collector comes and picks it up when the last reference to it goes away. In C++, Object o; is the actual object, which will go away at the end of its scope.

So if std::vector only stores references to the objects you push_back(), then it will be utterly useless for things like this:

std::vector<int> numbers;
for(/* loop condition */) {
    int number = GetUserInput();
    numbers.push_back(n);
}

Since number will go away at the end of the loop, numbers would hold references to something that will not exist if std::vector was implemented by storing only references. If std::vector actually stored the values, you could access them even after the loop.

C++11 supports move semantics, so if the thing you're pushing back is actually a temporary that will go away soon, it'll move the internals of the object into the vector storage instead of copying. You can also explicitly use C++11's std::move() to "force" the move during push_back(). But vector will copy the value in every other case. It's an implementation detail to optimize the performance of vectors.




回答2:


Using push_back will always create a copy of the object that is being stored.

If you are using c++11, then there are two ways to avoid the copy :

  • use the emplace method
  • move the created object into the vector: vec.push_back( std::move( obj ) );

If you are not using c++11, then the only thing you can do is to use pointers or boost::shared_ptr as vector types.



来源:https://stackoverflow.com/questions/8543854/when-adding-an-element-to-a-vector-how-to-know-that-a-copy-of-the-object-is-goi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!