2017-05-04 69 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範式,在這種情況下,一旦超出範圍,對象將自動被釋放。

相關問題