向向量添加元素时,如何知道将要制作对象的副本? [英] When adding an element to a vector, how to know that a copy of the object is going to be made?

查看:51
本文介绍了向向量添加元素时,如何知道将要制作对象的副本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的班级中有一个名为 LastQueryInfo lastQuery 的对象.每次这个对象发生变化时,我都会将它添加到一个名为 history 的向量中.

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

最初,当我执行 history.push_back(lastQuery) 时,我不知道会发生什么 - 向量会复制对象吗?还是会保留对它的引用?因此,如果稍后我修改 lastQuery,是否会修改历史向量中的所有对象(假设它们是引用)?

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?

经过一些测试,我发现 history.push_back(lastQuery) 确实会复制对象,然后将其添加到向量中.但是我怎么知道不做任何测试呢?我怎么知道 C++ 什么时候会做一个副本,什么时候会添加实际的对象?

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?

推荐答案

std::vector 总是 存储一个副本push_back().所以修改你传入的值不会影响存储在向量中的值.它不像 Java 或 C#,其中 Object o; 实际上是对对象的引用,并且该对象一直存在,直到垃圾收集器在最后一个引用消失时来收集它.在 C++ 中,Object o; 是实际的对象,它将在其作用域结束时消失.

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.

因此,如果 std::vector 只存储对您 push_back() 对象的引用,那么对于这样的事情,它将完全没用:

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

由于 number 将在循环结束时消失,numbers 将保存对如果 std::vector 是通过只存储引用来实现的.如果 std::vector 实际存储了这些值,您甚至可以在循环之后访问它们.

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 支持 移动语义,所以如果你推回的东西实际上是一个很快就会消失的临时对象,它会将对象的内部移动到向量存储中,而不是复制.您还可以显式地使用 C++11 的 std::move()push_back() 期间强制"移动.但是 vector 会在所有其他情况下复制该值.这是优化vectors性能的一个实现细节.

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.

这篇关于向向量添加元素时,如何知道将要制作对象的副本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆