2011-08-31 49 views
3

我正在尋找一種方法來確保在堆上執行的對象總是在我完成時釋放。如何確保(像一個試圖終於)銷燬一個HEAP ALLOCATED對象

我知道,如果它被分配到堆棧上,我可以使用RAII來確保它會被照顧 - 不幸的是,這對我(至少是直接的)不起作用,因爲所討論的對象實際上是由調用一個api函數,然後它返回一個指向它在堆上創建的對象的指針。

所以,從概念上講,我想要做的是一樣的東西:

TheApi::ApiObject* p_myObj = TheApi::createAnApiObj(); 
try 
{ 
    doStuffWithMyObjThatMayError(p_myObj); 
} 
finally 
{ 
    delete p_myObj; 
} 

我能想到的唯一要做的是使某種虛擬清理階級,創造者的一個實例在堆棧上:

class MegaMaid 
{ 
private: 
    TheApi::ApiObject* toFree; 
public: 
    MegaMaid(TheApi::ApiObject* toFree) 
    { 
     this->toFree = toFree; 
    } 

    ~MegaMaid() 
    { 
     delete toFree; 
    } 
}; 

void doStuff() 
{ 
    TheApi::ApiObject* p_myObj = TheApi::createAnApiObj(); 
    TheApi::ApiObject* p_myObj; 
    MegaMaid cleaner(p_myObj); 
    doStuffWithMyObjThatMayError(p_myObj); 
} 

有沒有更好的方法來實現這個目標?或者這是公認的解決方案?

+0

而你不能修復(破損的)API? – Nemo

+1

如果一個API函數返回一個指針,你是否110%確定可以調用該指針上的'delete'? API是否這樣說?還是它提供了自己的清理功能? –

+0

尼莫 - 不,不知道,我堅持原封不動的API。 = P –

回答

6

您仍然可以在由函數返回的指針上使用RAII。你可以使用智能指針(這正是你所描述的虛擬類)是這樣的:

std::unique_ptr<TheApi::ApiObject> p_myObj(TheApi::createAnApiObj()); 
+0

嗯,謝謝...,這似乎完全一樣,我一直在尋找! –

+0

所以我可能已經說了一點草率......在我的特殊情況下,你實際上應該調用一個關於ApiObject的方法,並刪除它...我知道,在api方面設計不佳,應該處理在ApiObject的析構函數中......處理這種情況的標準方法是什麼? –

+2

@PaulMolodowitch使用自定義刪除程序。 'std :: unique_ptr '實際上是'std :: unique_ptr >'where std :: default_delete :: operator()(T * p);''刪除p;''。你可以使用'std :: unique_ptr 來做你想要的破壞時間。 –

6

「虛擬類」被稱爲「智能指針」。您應該查看std::auto_ptrboost::shared_ptr。它們提供了您所期望的。