2013-07-31 61 views
2

我是智能指針的新手。不過,我對它有一個基本的瞭解。我觀察到的是,智能指針必須按照其創建的相反順序被銷燬,否則智能指針可能會行爲不端。考慮以下情況:多線程環境中的智能指針

sharedPtr<abc> my_ptr(new abc); //smart pointer created. Instance counter = 1. 
func1(my_ptr);     //copy constructor in smart pointer called. Instance counter=2 
func2(my_ptr);     //copy constructor in smart pointer called. Instance counter=3 
func3(my_ptr);     //copy constructor in smart pointer called. Instance counter=4 

現在,是不是必要的,func3()先退出,然後func2()func1()終於my_ptr。

問:如果my_ptr超出範圍第一(&因此試圖刪除abc),與func1()func2()func3()仍參考abc(通過智能指針)?

回答

4

其實,你觀察到的是錯誤的。

智能指針的要點是消除摧毀對象的責任。這意味着當參考計數達到0時,對象將被刪除:首先破壞哪個指針並不重要。

在你的情況下,當my_ptr超出範圍,這將是(假設你不把最好保留一份副本在一個你func()

這是引用計數應該是什麼:

{ 
sharedPtr<abc> my_ptr(new abc); //smart pointer created. Ref counter = 1. 
func1(my_ptr);     // Ref counter=2 while in func1 
// Ref count is 1 again. 
func2(my_ptr);     // Ref counter=2 while in func2 
// Ref count is 1 again. 
func3(my_ptr);     // Ref counter=2 while in func3 
// Ref count is 1 again. 
} // my_ptr goes out of scope, ref count reach 0, and abc is deleted. 
+0

但是,這是我的問題: 我想在堆上創建一個事件對象,並將此事件(通過指針傳遞)傳遞給觀察者類,觀察者類又將事件存儲在各自的向量中進行處理晚些時候。問題:如何確保所有觀察員在有人試圖刪除之前處理​​事件?誰應該刪除在堆上創建的事件?我不想在vecotr <>中複製事件,而只是想在vecotr <>中存儲一個指向事件的指針。 –

+0

而不是'vector '去'vector >'。每個觀察者都會保留'shared_ptr'只要它需要(我想直到事件得到處理),並且當它不再需要對事件的引用時,它將從向量中移除它。當最後一個觀察者釋放指針時(即將其從矢量中移除),該事件將被自動刪除。 – Xaqq

+0

這正是我想要使用的。但是,我正在使用自定義shared_ptr類而不是標準庫。 (我這樣做,只是爲了理解這個概念)。 這是問題: void publishEvent() { sharedPtr start_ev(new start); \t \t //創建一個事件 - 在堆上開始。 start_ev - ref counter = 1 notifyObservers(start_ev); \t \t \t //所有觀察者將事件保存在向量> } // oops !!! start_ev刪除事件開始.. 這是否與一個錯誤實現的自定義sharedPtr? –

1

我不知道您的自定義sharedPtr,但對於標準std::shared_ptr它像(來自鏈接參考):

的對象被破壞,當以下情況之一發生內存釋放:

  • 最後剩下的擁有該對象的shared_ptr被銷燬。

  • 擁有該對象的最後剩下的shared_ptr通過operator =()或reset()分配給另一個指針。

所以對於std::shared_ptr你可以圍繞它傳遞或只要你想,這些副本的破壞的順序並不重要製作多個副本。

1

我所觀察到的是,它是必要的智能指針,以在他們的創作

那麼相反的順序被摧毀,共享智能指針的存在的唯一理由是,一個當他們被毀壞時不應該在意。當最後一個共享指針被銷燬時,它會銷燬該對象,如「最後一個離開的人關閉燈光」一樣。