我试图理解以下内容(假设 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();
}
根据我的理解,当 s
返回 vector 并分配给 vm
时,这是作为一个拷贝(按值)完成的。因此,如果 s
超出范围并调用它的析构函数,vm
有自己的拷贝,其结构不受影响。但是,按值传递效率不高。因此,如果您将其更改为通过引用传递:
vector<MyStorageClass*>& getItems()
{
for(int i = 0; i < 10; ++i)
{
v.push_back(new MyStorageClass());
}
return v;
}
您传递 v
的内存位置(在 Storage 类中)。但是您仍然使用 =
运算符将它的拷贝分配给 Main 类中的 vector vm
。因此,vm
独立于 v
,如果 Storage
析构函数被调用 vm
不受影响。
最后,如果 getItems
返回一个引用,并且主要是您有以下内容:
main()
{
storage s;
vector<MyStorageClass*> &vm = s.getItems();
}
现在,vm
保存着v
的地址。所以它受到存储析构函数的影响。
问题:我上面说的是真的吗?
最佳答案
是的,您理解正确。现在,如果您想将它提升到一个新的水平,请从找出这不好的原因开始:
- 返回指针或对类内部的引用会破坏封装。
- 一旦相应的
s
对象被销毁,您获得的引用将成为悬挂引用,从而打破引用始终有效的不变量。 - 通过返回一个指针 vector ,您让调用者想知道他是否必须删除这些指针。
更好的解决方案是让 storage
公开方法 begin
和 end
,它们从 s
返回相应的迭代器>。或者,您可以使用 Visitor - 需要对 s
进行操作的算法的模式。
此外,在您的情况下, vector s
似乎应该拥有它包含的对象。这将是使用 boost::ptr_vector
的一个很好的指标。 .
关于c++ - 指针的返回 vector ——理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8342226/