2013-11-27 94 views
6

我有一個Thread類像波紋管我可以從它的類方法調用析構函數嗎?

class Thread { 
public: 
    Thread(); 
    ~Thread(); 
    void start(); 
    void stop(); 
} 

,所以我需要調用從stop()方法的析構函數,這是一個好的辦法做到這一點?

+3

不,當對象的一生結束時會發生什麼?可能會更好地描述您需要的內容(從技術上講,當它可能工作,但你想限制你的課程只能在那些角落案件工作?) – juanchopanza

+0

你可以'刪除它;'它(如果它是一個堆棧var),但它是非常危險的。你爲什麼要這樣?你不能在調用'stop'或者使用一些智能指針後'刪除'對象嗎?或者只是堆棧變量? –

+0

@KirilKirov:在哪個堆棧上會有一個'Thread'?不是在它自己的堆棧上,而是在其他一些線程的堆棧上,大概是這樣。 – MSalters

回答

5

delete this; 

但要小心。您不應再使用已刪除的對象this和非靜態成員。

 

另一種方法是調用析構函數

~Thread(); 

 

但問題是,爲什麼你需要調用析構函數?這不合邏輯。您可以編寫代碼來管理私有方法中的資源並調用它。

+4

即使線程在堆棧上? –

+1

+1,你可能想添加,不要在delete語句後面使用'this'或任何非靜態成員變量。 –

+0

@CommanderCorianderSalamander:這個問題意味着析構函數必須被顯式調用,即它不會被調用,因爲對象超出了範圍。 – MSalters

2

你可以使用這個語法:

~Thread(); 

但我懷疑,如果你真的需要的C此功能++。也許你應該更好地設計你的班級。

顯式調用析構函數的一個法律案例是在自定義內存管理器中,您不能使用delete運算符刪除該對象。

+1

正確的語法,堅實的建議。 你很少想要像這樣發起對自己的毀滅,人們想要幾乎總是想要錯誤的事情。 – RichardPlunkett

+1

@RichardPlunkett在展示位置之外 - 新的對象管理,我很難想出任何人會願意這樣做的原因。 – WhozCraig

+0

@WhozCraig同意。在C++規範§12.4.14中:「很少需要顯式調用析構函數,這種調用的一種用法是使用具有放置選項的新表達式放置在特定地址處的對象。這樣使用對象的顯式放置和銷燬有必要處理專用硬件資源和編寫內存管理設施。「 –

0

編號

我認爲從類代碼中調用析構函數是不好的做法。 如果您需要在析構函數中完成清理,則應使用cleanup()函數來封裝該工作,並從stop和destructor調用該函數(如果相關)。

很明顯,這樣的解決方案需要保持對象的狀態,以瞭解它是否已經清理乾淨,以避免不必要的工作和多次釋放資源,這些資源可能不再是您的。

特別爲你的情況,我不知道你爲什麼要從停止函數中刪除線程,如果有一些機制管理線程 - 它應該從外部分配/取消分配線程,而不是線程本身在停止時釋放自己的記憶。 (線程應該執行如上所述的清理,但不強制對自己的析構函數調用)

+0

即使'cleanup()'和析構函數完全一樣嗎?例如我有一些互斥體來清理,析構函數(和'cleanup()',相同),只是嘗試檢測當前線程擁有哪個互斥鎖並解鎖它。在某些時候,我想要執行'cleanup()',但是當類實例被銷燬時,我想要解鎖互斥鎖。所以他們分享完全相同的代碼。 –

0

否。不要這樣做。

使線程擁有另一個對象。

當您致電stop()時,線程應告訴其擁有者它已準備好被刪除(請確保您鎖定自己,以便擁有者在完成之前不會刪除)。然後讓對象的所有者酌情進行清理(希望在不久的將來)。

+0

downvoter能啓發我們其餘的人嗎?這對我來說似乎是非常合理的建議,這可能會在大多數情況下導致更好的代碼。 –

0

其他人說不要在成員函數中調用delete this,而是通知所有者該對象已準備好被刪除。

我有一種服務,可以創建工人,但在創建後不關心他們。

從服務類中:

Worker* w; 
[...] 
while (1) { 
    [...] 
    w = new Worker(); 
    [...] 
} 
從工人階級中

然後:

void Worker::doWork() { 
    [...] 
    [...] 
    delete this; 
} 

所有服務類不就是讓新員工,使工人階級的外面有沒有除了指針w之外的每次創建新工作人員時丟棄的對工人的引用。

在這種情況下,我覺得很有道理調用delete this工人內部時,它沒有更多的工作要做(只要delete this;doWork()最後聲明和doWork()後沒有succesive成員的呼叫。

但是,如果您要存儲創建的工作人員的每個實例,則不會再出現這種情況。

相關問題