c++ - 指针的返回 vector ——理解

标签 c++ memory-management pointers

我试图理解以下内容(假设 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 的地址。所以它受到存储析构函数的影响。

问题:我上面说的是真的吗?

最佳答案

是的,您理解正确。现在,如果您想将它提升到一个新的水平,请从找出这不好的原因开始:

  1. 返回指针或对类内部的引用会破坏封装。
  2. 一旦相应的s对象被销毁,您获得的引用将成为悬挂引用,从而打破引用始终有效的不变量。
  3. 通过返回一个指针 vector ,您让调用者想知道他是否必须删除这些指针。

更好的解决方案是让 storage 公开方法 beginend ,它们从 s 返回相应的迭代器>。或者,您可以使用 Visitor - 需要对 s 进行操作的算法的模式。

此外,在您的情况下, vector s 似乎应该拥有它包含的对象。这将是使用 boost::ptr_vector 的一个很好的指标。 .

关于c++ - 指针的返回 vector ——理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8342226/

相关文章:

c - 当您传递已分配的值指针时,究竟会发生什么?

c++ - Qt5:使用 QSortFilterProxyModel 时拖放

c - 为什么我从 void** 初始化的结构中获取垃圾值

ios - AFNetworking 的 requestWithMethod :path:parameters: Returning NSMutableURLRequest That Doesn't Persist

c++ - 删除动态数组?

c - 关于指针的前向引用?

c++ - 是否有标准模板类用于使用指针管理对象并提供复制/move/分配操作?

c++ - __func__ 指针的两个 constexpr 实例的差异仍然是 constexpr 吗?

c++ - 可以访问在类声明中声明的 typedef 吗?

c++ - 重载 New 时,New 与 Malloc