nf3*_*743 4 c++ pointers memory-management
我试图了解以下内容(让我们假装MyStorageClass很大):
class MyStorageClass
{
public:
string x;
string y;
string z;
};
class storage
{
public:
storage();
~storage()
{
vector<MyStorageClass *>::iterator it = myVec.begin(); it != myVec.end(); it++)
{
delete *it;
}
vector<MyStorageClass*> getItems()
{
for(int i = 0; i < 10; ++i)
{
v.push_back(new MyStorageClass());
}
return v;
}
private:
vector<MyStorageClass*> v;
};
main()
{
storage s;
vector<MyStorageClass*> vm = s.getItems();
}
Run Code Online (Sandbox Code Playgroud)
从我的描述中,当s
返回向量并被赋值给vm
它时,作为副本(按值)完成.因此,如果s
超出范围并将其称为析构函数,vm
则拥有自己的副本,其结构不受影响.但是,通过价值传递效率不高.因此,如果您将其更改为通过引用传递:
vector<MyStorageClass*>& getItems()
{
for(int i = 0; i < 10; ++i)
{
v.push_back(new MyStorageClass());
}
return v;
}
Run Code Online (Sandbox Code Playgroud)
您传递v
(在类Storage中)的内存位置.但是你仍然使用=
运算符将它的副本分配给vm
Main类中的向量.因此,如果析构函数不受影响,vm
则独立于此.v
Storage
vm
最后,如果getItems
返回一个引用,并且在main中你有以下内容:
main()
{
storage s;
vector<MyStorageClass*> &vm = s.getItems();
}
Run Code Online (Sandbox Code Playgroud)
现在,vm
握住地址v
.因此它受Storage Destructor的影响.
问题:我上面说的是真的吗?
是的,你已经正确理解了这一点.现在,如果你想把它提升到一个新的水平,首先找到原因,这是坏事:
s
-object被销毁,你获得的引用将成为悬挂引用,从而打破引用始终有效的不变量.更好的解决方案是storage
公开方法begin
并end
返回相应的迭代器s
.或者,您可以将Visitor -pattern用于需要操作的算法s
.
此外,在您的情况下,似乎矢量s
应该拥有它包含的对象.这将是一个很好的使用指标boost::ptr_vector
.