使用析构函数删除成员向量中的堆分配对象
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);
一旦函数超出范围,m
和 child
将调用它们的析构函数,因为它们不是动态分配的,从而将它们都销毁。
但是,child
指针指向的内容不会以与m
和child
类似的方式销毁,因为它通过 new
在免费商店中动态分配。在这种情况下,您需要为放置在免费商店中的每个对象调用 delete
,就像您在上面所做的那样。
这就是为什么人们在评论中建议您使用智能指针,因为它们遵循 RAII 范例,在这种情况下,一旦对象超出范围,它们将自动释放。
我有一个递归问题要解决。如果给定的操作是可能的,则可能存在其他子操作,等等。我的解决方案是 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);
一旦函数超出范围,m
和 child
将调用它们的析构函数,因为它们不是动态分配的,从而将它们都销毁。
但是,child
指针指向的内容不会以与m
和child
类似的方式销毁,因为它通过 new
在免费商店中动态分配。在这种情况下,您需要为放置在免费商店中的每个对象调用 delete
,就像您在上面所做的那样。
这就是为什么人们在评论中建议您使用智能指针,因为它们遵循 RAII 范例,在这种情况下,一旦对象超出范围,它们将自动释放。