2009-01-15 40 views
28

今天,我看到了一些遺留代碼。在析構函數中有一個像「delete this」的聲明。我想,這個調用將是遞歸的。它爲什麼工作?「刪除這個」有什麼用?

我Y上做了一些快速搜索!我發現,如果有需要限制用戶創建堆棧對象,我們可以讓析構函數私有,並提供刪除實例的接口。在提供的接口中,我們必須在這個指針上調用delete。

是否有任何其他情況使用這些語句?

回答

32

「刪除」通常用於參考計算的對象。對於ref計數對象,何時刪除的決定通常放在對象本身上。這是Release方法看起來像[1]的一個例子。

int MyRefCountedObject::Release() { 
    _refCount--; 
    if (0 == _refCount) { 
    delete this; 
    return 0; 
    } 
    return _refCount; 
} 

ATL COM對象是這種模式的主要例子。

[1]是的,我知道這是不是線程安全的。

+0

雖然refcounted對象的自我刪除是一個非常常見的模式,但我認爲最初的問題是關於將其放入析構函數中,而不是Release()函數,在這種情況下它只是瘋狂。 – rmeador 2009-01-15 17:57:56

+0

@rmeador,真的有兩個問題。標題和最後一句都表明想要知道「刪除這個」的有效用法。我希望我能回答。中間確實提出了一個「爲什麼要在dtor中刪除它」的問題。我同意這樣做似乎是瘋了。 – JaredPar 2009-01-15 18:38:52

24

delete this是不是在析構函數有效。它可以在別處使用。但這只是一個好主意。 wxWidgets框架將它用於它們的線程類。它有一個模式,當線程結束執行時,它會自動釋放系統資源和自身(wxThread對象)。我發現它很煩人,因爲從外面看,你無法知道它是否有效 - 你不能再調用像IsValid這樣的函數,因爲該對象不存在。除了它不能用於非動態對象的問題之外,這與delete this的主要問題有異曲同工之妙。

如果你這樣做,確保你不要觸摸任何數據成員,或調用任何成員函數了您刪除這樣的對象。最好將它作爲非虛擬,受保護或私有函數中的最後一條語句。調用刪除在虛擬和/或公共函數中也是有效的,但我會限制該方法的可見性。

C++ FAQ有一個關於它的條目。 C++對我的要求標準報價以上(3.8p5):

對象的生命週期之前已經開始,但是對象將佔用已分配或對象的生命週期結束後和前儲存後對象佔用的存儲器被重新使用或釋放​​,可以使用任何指向對象將位於或位於其中的存儲位置的指針,但只能以有限的方式使用。 [...] 如果對象將是或者是具有非平凡析構函數的類類型,並且該指針用作delete-expression的操作數,則該程序具有未定義的行爲。

當對象的析構函數開始執行時,生存期結束。請注意,對於正在構建和銷燬的對象(例如,您可以訪問非靜態數據成員),該段後面的規則有例外情況,詳見12.7

3

那地方被認爲是很好的理由在早期的C++天做到這一點。例如ref ref對象的自我刪除(如JaredPar所說)。 據我所知,從長遠來看,他們都被認爲是一個壞主意。

2

在雙向鏈表中,可以在不引用任何外部結構(如高級「list」對象)的情況下刪除節點。這使得每個節點處理自己的重新分配(可能與一個互補的靜態方法來處理來自同一個內存池的初始分配)是合理的。在這種情況下,節點對象可以自行刪除(當用戶請求時)。

void RemoveAndDeallocate() 
{ 
    LinkedListNode *current_prev = prev, *current_next = next; 
    current_prev->next = current_next; 
    current_next->prev = current_prev; 
    delete this; 
} 

雖然,這也是合理的一個節點從一個鏈表中並鏈接到另一個列表,沒有任何重新分配內存,所以對於單個刪除操作無條件釋放內存,這是不可取的。

相關問題