2009-06-19 44 views
3
Callback* p = new Callback; 
function(p); 

如果我想刪除回調對象,何時以及如何刪除它?何時讓對象自己刪除?

如果它被提前刪除,則回調可能會因分段錯誤而失敗。

+0

這將取決於你。 – 2009-06-19 15:22:16

回答

17

對此的最佳解決方案是使用智能指針。
您用回調函數初始化指針並將其傳遞給函數。當函數或任何過程完成時,回調將被智能指針自動刪除。
一個好的智能指針實現是boost::shared_ptr<>

+0

如果你需要一個共享指針,然後使用你的編譯器提供的tr1 :: shared_ptr implmentation(假設它是現代的),否則使用boost :: scoped_ptr用於RAII,幾乎沒有開銷。 – Patrick 2009-06-19 18:42:28

+0

在這種情況下,std :: auto_ptr是一個更好的智能指針。然後您將回調對象的所有權傳遞給該函數。 – 2009-06-19 20:29:18

1

你可以有一個增量/減量計數的時候使用回調。當它被使用時,遞增計數,當它不再使用時,遞減計數。當它達到0或-1時釋放它。

1

持有回調函數(執行回調函數的回調函數)的「調用者支持者」對象可能是正確的所有者(決定回調函數的生存期,特別是使用delete來取消回調對象,持有auto_ptr等),當且僅當它的語義是讓它確定什麼時候不需要進一步的回調 - 從問題中提供的這樣少量的信息是不可能分辨出來的。

您可能還需要各種方式爲創建回調(並傳遞它的所有權給調用者,支持者),明確提出了「來電者支持者」刪除回調對象(並執行沒有更多的回調代碼)當所述代碼是確定不再需要更多回調的代碼時。

其他答案提到比auto_ptr更聰明的指針來解決「誰擁有這個」消失的問題(boost的shared_ptr,手動引用計數,...) - 如果你被迫使用C++出於其他原因,但真的很想用垃圾收集語言,但是,如果您專門選擇C++是因爲它可以完全控制內存使用情況,那麼正確確定對象所有權和生命期問題不是可選的(並且它可以嚴格優化您的資源與任何種類的或多或少的自動化「垃圾收集」相比 - 只有當您需要嚴密控制您的資源使用情況時,纔會重要;當您的時,這一點非常重要。

1

假設func()是使用該特定Callback對象的唯一函數,並且此代碼總是按照創建Callback對象的順序執行,我會在調用func()後將其放入。這樣,如果你必須編輯func(),你不必擔心回調對象被刪除的地方。它還確保所有指針都被清空,因爲函數完成時func()的指針應該已經停止存在,唯一要做的就是刪除指向它的指針。

我很抱歉,如果我對C++中指針的理解是有缺陷的,並導致我給出一個不正確的答案,我總是對此有點困惑。

3

如果如你所說的那樣,這意味着只有一個參考回調指針FUNC()之後被執行的代碼是微不足道的,我相信一個auto_ptr就足夠了:

std::auto_ptr<Callback> p(new Callback); 
func(p.get()); 

這也保證了應func()拋出異常,內存仍然會被釋放。

1

如果你的代碼是你所寫的內容一樣簡單,而且func()直接調用在某些點回調,那麼這應該是足夠了:

Callback p; 
func(&p); 

但是,如果func()節省引用或指針回調其他地方,您需要跟蹤該參考的生命週期。