dan*_*ani 2 c++ pointers reference vector
我将一些对象存储在向量中.当我调用这样一个使用引用的对象的成员函数时,程序终止(没有错误).我写了下面的代码做了一些测试.它在添加元素之后接缝,第一个条目中的引用失败.为什么这样做,我该怎么做才能避免这个问题呢?当我使用指针而不是引用时,它的行为完全相同.
#include <iostream>
#include <vector>
using namespace std;
class A{
public:
A(int i) : var(i), ref(var) {}
int get_var() {return var;}
int get_ref() {return ref;}
private:
int var;
int& ref;
};
int main ()
{
vector<A> v;
for(unsigned int i=0;i<=2 ;i++){
v.emplace_back(i+5);
cout<<"entry "<<i<<":"<<endl;
cout<<" var="<<v.at(i).get_var()<<endl;
cout<<" ref="<<v.at(i).get_ref()<<endl;
}
cout<<endl;
for(unsigned int i=0;i<=2 ;i++){
cout<<"entry "<<i<<":"<<endl;
cout<<" var="<<v.at(i).get_var()<<endl;
cout<<" ref="<<v.at(i).get_ref()<<endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
entry 0:
var=5
ref=5
entry 1:
var=6
ref=6
entry 2:
var=7
ref=7
entry 0:
var=5
ref=0 /////////////here it happens!
entry 1:
var=6
ref=6
entry 2:
var=7
ref=7
v has 3 entries
Run Code Online (Sandbox Code Playgroud)
这是因为你对emplace_back的调用导致向量调整大小.为了做到这一点,向量可能必须或可能不必将整个向量移动到存储器中的不同位置.您的"ref"仍然引用旧的内存位置.
这实际上是否发生在某种程度上依赖于实现; 编译器可以自由地为向量保留额外的内存,这样他们就不必在每次向后面添加内容时重新分配.
它在emplace_back的标准文档中提到:
迭代器有效性
如果发生重新分配,则与此容器相关的所有迭代器,指针和引用都将失效.否则,只有结束迭代器失效,并且所有其他迭代器,指针和对元素的引用都保证在调用之前引用它们所引用的相同元素.
为了避免这个问题,您可以(如评论中的JAB建议)动态创建引用,而不是将其存储为成员变量:
int& get_ref() {return var;}
Run Code Online (Sandbox Code Playgroud)
...虽然我宁愿使用智能指针而不是这种东西.
或者,正如RnMss建议的那样,实现复制构造函数,以便每当向量复制对象时它都引用新位置:
A(A const& other) : ref(var) {
*this = other;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
375 次 |
| 最近记录: |