当push_back新元素到std :: vector时,C ++引用会发生变化

时间:2013-10-25 10:47:32

标签: c++ c++11 reference stdvector push-back

我不知道该怎么做 - 请告诉我下面的代码有什么问题。我修改了我的代码以将其简化为最简单的术语。有一个带有一堆MyNode对象的std :: vector。第一步是获取对这些节点之一(Data m_data)的一个数据元素的持续引用 - 在下面的示例中,在插入第二个节点之前只有一个节点,如下所示:

const cv::Data& currData = m_nodesVector[currIndex].GetData();
MyNode node(...);
m_nodesVector.push_back(node);

正好在vector :: push_back调用中,currData的值发生了变化!!我只是不明白。如何将新节点插入向量会将值引用更改为第一个节点的数据?!!请注意,在“创建”第二个节点时,该值不会更改 - 但是在插入到std :: vector中的操作时。我的意思是,我认为std :: vector可能会重新调整一些内存,但这不应该改变引用权吗?

Compiler = VS 2012

谢谢你们。非常感谢。

4 个答案:

答案 0 :(得分:16)

  

如何将新节点插入向量会将值引用更改为第一个节点的数据?!!

因为向量的元素存储在连续的数组中。当数组中没有空间时,所有元素都会移动到更大的元素,使所有迭代器,指针和对它们的引用无效。

  

我想std :: vector可能会重新调整一些内存,但这不应该改变引用权吗?

当然会。引用是指特定地址的特定对象;如果它被移动,它不会跟踪它。

如果您需要稳定的引用,请使用deque;或者(如果可能的话)使用reserve将矢量的容量设置得足够大,以包含您可能添加的所有内容。只有在需要重新分配时才会使引用无效,并且仅当您尝试超出当前容量时才会发生引用。

或者,您可以存储对象的索引,而不是对它的引用。

答案 1 :(得分:3)

向向量添加新项目时,可以重新分配其中的数据以适合新项目。这意味着对项目(及其成员)的引用和指针将无效。

答案 2 :(得分:0)

您可以通过move-constructor更新指针:

A(A&& a): b(a.b) { b.ptr  = this; };

答案 3 :(得分:0)

访问http://www.cplusplus.com/reference/vector/vector/push_back/

当您尝试添加新项目时,它将检查下一个相邻内存是否空闲。 如果免费,则将新项目添加到下一个可用位置,否则首先重新分配向量,并添加新项目。