2011-03-23 70 views
0

我目前的項目有一個跟蹤/代理C++對象的機制,以安全地將它們暴露給腳本環境。它的一部分功能是在C++對象被銷燬時得到通知,以便在腳本環境中安全地清除對該對象的引用。在析構函數中發出sigC++信號是否安全?

要做到這一點,我已經定義了以下類:

class DeleteEmitter { 
public: 
    virtual ~DeleteEmitter() { 
     onDelete.emit(); 
    } 
    sigc::signal<void> onDelete; 
}; 

那麼我有可能需要暴露在腳本環境中的任何類從該類繼承。當代理層被調用時,它將一個回調函數連接到onDelete信號,並在對象被銷燬時被通知。

光測試表明這可以工作,但在實際測試中,我在代碼的無關部分看到了特殊的內存損壞(讀取:malloc/free中的崩潰)。在valgrind下運行表明,在釋放對象後可能會出現雙重釋放或繼續使用,所以可能在類中有一箇舊的錯誤,該錯誤僅在將DeleteEmitter添加到其繼承層次結構後纔會暴露。

在調查過程中,我發現在析構函數中發出sigC++信號可能不安全。如果回調嘗試使用被刪除的對象,顯然這將是一件壞事,但我可以確認這不是發生在這裏的事情。假設,有人知道這是否安全嗎?是否有更常見的模式來達到相同的結果?

回答

2

C++規範保證你的對象中的數據成員不會被銷燬,直到你的析構函數返回,所以onDelete對象在那個點上是未觸及的。如果您確信該信號不會間接導致對該對象的任何讀取,寫入或方法調用被銷燬(如果DeleteEmitter是另一個對象的一部分,則爲多個對象)或生成C++異常,則它是「安全的」 「。當然,假設您不在多線程環境中,在這種情況下,您還必須確保其他線程不會產生干擾。

+0

非常多這個 - 對象仍然像平常一樣存在,同時'onDelete.emit()'熄滅,所以只要它不拋出,它就是安全的。 – Puppy 2011-03-23 02:00:55

相關問題