使用析构函数删除成员向量中的堆分配对象

Use Destructor to Delete Heap-allocated Objects in Member Vector

我有一个递归问题要解决。如果给定的操作是可能的,则可能存在其他子操作,等等。我的解决方案是 class 这样的:

// MyObj.h
#include <vector>
class MyObj
{
    private:
        std::vector<MyObj*> _children;
    public:
        void addChild(MyObj* m);
}

// MyObj.cpp
#include "MyObj.h"
void MyObj::addChild(MyObj* m)
{
    MyObj::_children.push_back(m);
}

我正在这样使用 class:

MyObj m;
MyObj *child = new MyObj();
m.addChild(child);

我的理解是,由于我在堆上分配了child,所以我需要稍后销毁它。如果创建该对象的代码不维护该引用,则将由父对象来销毁它。这样定义析构函数合适吗:

MyObj::~MyObj()
{
    for (std::size_t i = 0; i < MyObj::_children.size(); i++)
    {
        delete MyObj::_children[i];
    }
}

我的做法是否正确,还是我的方法有缺陷?

PS:如果这是直接重复,我深表歉意,因为我知道已经有很多关于析构函数的问题;我读了很多书,但仍然没有信心。我对 C++ 非常缺乏经验,认为直接的问题对我最有帮助。

除非绝对必要,否则不应使用 new。一旦你这样做了,你就有责任释放你动态分配的内存。在您上面的代码中:

MyObj m;
MyObj *child = new MyObj();
m.addChild(child);

一旦函数超出范围,mchild 将调用它们的析构函数,因为它们不是动态分配的,从而将它们都销毁。

但是,child指针指向的内容不会以与mchild类似的方式销毁,因为它通过 new 在免费商店中动态分配。在这种情况下,您需要为放置在免费商店中的每个对象调用 delete,就像您在上面所做的那样。

这就是为什么人们在评论中建议您使用智能指针,因为它们遵循 RAII 范例,在这种情况下,一旦对象超出范围,它们将自动释放。