2017-05-04 50 views
1

我有一个递归问题,我试图解决。如果给定的动作是可能的,则可能存在额外的子动作,等等。我的解决办法是这样的一类:使用析构函数删除成员矢量中的堆分配对象

// 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); 
} 

我使用的类是这样的:

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]; 
    } 
} 

我是在正确的轨道上,还是我的方法有缺陷?我很抱歉,如果这是一个直接重复,因为我知道有很多问题已经处理了析构函数;我读了一堆,但仍然没有自信。我对C++相当缺乏经验,并认为直接问题对我最有帮助。

+2

您应该使用智能指针,例如['std :: unique_ptr'](http://en.cppreference.com/w/cpp/memory/unique_ptr)或['std :: shared_ptr'](http:/ /en.cppreference.com/w/cpp/memory/shared_ptr)来处理对象所有权,而不是原始指针。作为一个副作用,你的问题是没有意义的。 –

+1

你必须决定你的班级是否拥有子女。如果确实如此,那么您将需要在上面执行您的代码。 – Spads

+1

我想指出,智能指针并不总是会节省一天的时间。他们带来自己的问题。在决定在整个项目中使用它们之前,请查看http://stackoverflow.com/questions/1905787/pros-and-cons-of-smart-pointers。 – Spads

回答

1

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

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

一旦函数超出范围,mchild必须就因为它们不是动态分配的称他们的析构函数,从而破坏他们俩。

然而,内容指向由child指针是以类似的方式销毁mchild因为它是在自由存储区经由new动态分配的。在这种情况下,您需要拨打delete来查找您在免费商店中放置的每个物品,就像您上面所做的一样。

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

相关问题