【问题标题】:destructor of a list delete virtual c++, basic questions列表的析构函数删除虚拟C++,基本问题
【发布时间】:2016-03-14 20:34:16
【问题描述】:

我有

class Derived : public Base
  1. 如果我有 std::list<G> 我如何释放列表?
  2. 如果我在A 中有std::list<G*>,如何释放该列表?
  3. 析构函数 - 哪个应该是虚拟的,A 的析构函数还是 B 的析构函数?
  4. 什么时候使用list.clear(),什么时候使用list.empty()
  5. 相同的问题 1-2 但使用 std::vector?

这是我的代码:

class Movie{
    list<Worker*> workersInMovie;
    list<G> g;

    Movie::~Movie() {
        for(list::<Worker*>::iterator it = workersInMovie.begin();
            it != workersInMovie.end(); ++it;)
            delete it;

        g.clear();
    }
};

【问题讨论】:

    标签: c++ list pointers memory destructor


    【解决方案1】:

    第一个问题:(列表)

    • 您的列表将在课程销毁时自动删除

    第二个问题:(列表指针)

    • 在类的析构函数中,您必须删除所有指针。使用了一个技巧std::shared_ptr&lt;&gt;,当没有人引用它时会自动销毁你的指针

    关于您提出的代码:

    使用auto(如果您使用的是 C11 或更新版本)比使用list::&lt;Worker*&gt;::iterator 更好

    for(auto it=workersInMovie.begin(); it!=workersInMovie.end(); it++){           
       delete *it; 
     }
    

    }

    【讨论】:

    • 所以我编辑了我的帖子,这是删除的正确代码吗?
    • 不能用那个..我的代码正确添加 delete *it 吗?
    • 是的,你的迭代器没问题,但是你的++it; 必须是++it(没有;
    【解决方案2】:

    您需要自己释放指针。该列表没有专门的指针,它对存储在列表中的数据一无所知。即使它知道它存储了指针(并且对其进行了专门化),那么它可能仍然不知道是否应该删除指针,如果你存储指向不应该删除的对象的指针怎么办?由new创建?

    【讨论】:

      【解决方案3】:
      1. 您调用std::list::clear 或让析构函数完成它的工作
      2. 在销毁每个元素之前调用delete(当然,只有当它被分配给new时)
      3. 基类析构函数必须声明virtual,它也会传播到派生类的成员函数声明
      4. std::list::clear 清除列表,std::list::empty 返回一个 bool,告诉您列表是否为空(很难检查参考?)
      5. std::list

      最干净的析构函数版本(仍然使用原始指针):

      Movie::~Movie() {
          for(auto x : workersInMovie)
              delete x;
      
          // no need to clear, std::list's destructor called afterwards
      }
      

      使用迭代器的工作版本:

      Movie::~Movie() {
          for(auto it = workersInMovie.begin();
              it != workersInMovie.end(); ++it)
              delete *it;
      }
      

      【讨论】:

      • 是的,看起来像,除了g.empty() 根据(4)应该是g.clear()
      • 你确定基类析构函数是虚拟的吗?我认为它的派生类
      • 顺便说一句,我可以将一个类声明为抽象类,即使它没有抽象方法?
      • 1.您为该类声明方法virtual,您希望从该类的派生类链中进一步向下发生多态性。 2. 你不能,这就是定义。如果你想让类抽象,你可以让析构函数成为纯虚拟的。
      • @Mooly 如果Movie 是基类,Movie::~Movie 应该是virtual
      猜你喜欢
      • 2020-12-27
      • 2011-08-12
      • 2020-11-26
      • 2012-04-18
      • 1970-01-01
      • 2023-03-23
      • 2017-05-31
      • 2016-08-14
      • 2015-04-30
      相关资源
      最近更新 更多