2010-05-17 58 views

回答

16

A weak_ptr擁有非擁有的引用,所以它引用的對象可能不再存在。使用weak_ptr所持有的原始指針本質上是危險的。

正確的做法是使用weak_ptr::lock()weak_ptr推廣到shared_ptr並從中獲取指針。

Boost weak_ptr documentation解釋了爲什麼提供get()功能作爲weak_ptr的一部分是不安全的,並且有可能導致問題的代碼示例。

+0

對於這個問題,如果你得到了一個'shared_ptr'的原始指針,那麼這個指針也會被銷燬......如果是Multithread,你甚至可以在運行中留下一個懸掛指針代碼if(!weak.expired())weak-> run();'因爲指向的對象可能在測試和方法執行之間被破壞(我認爲方法本身被正確同步)... – 2010-05-17 15:23:19

+3

@Matthieu:當然你*可以*,就像你可以留下一個懸掛指針一樣,如果你顯式地刪除一個對象但保留一個指針。必須將'weak_ptr'提升爲'shared_ptr'的一點是,它鼓勵您按照通常用於'shared_ptr :: get'的規則正確地使用原始指針。對於直接從'weak_ptr'獲取的原始指針的使用,沒有等同的方法。 – 2010-05-17 18:11:42

2

首先需要在獲取原始指針之前從weak_ptr派生shared_ptr。

您可以撥打lock得到shared_ptr的,或shared_ptr的構造函數:

boost::weak_ptr<int> example; 
... 

int* raw = boost::shared_ptr<int>(example).get(); 
+8

正如所寫,這是不安全的 - 如果在臨時'shared_ptr'被銷燬時刪除該對象,則可能會留下一個懸掛指針。只要你使用原始指針,你應該保持'shared_ptr'。 – 2010-05-17 15:14:06

3

這是一個老問題和接受的答案是好的,所以我毫不猶豫地張貼其他的答案,但有一點似乎缺少的是一個很好的習慣用法例如:

boost::weak_ptr<T> weak_example; 
... 
if (boost::shared_ptr<T> example = weak_example.lock()) 
{ 
    // do something with example; it's safe to use example.get() to get the 
    // raw pointer, *only if* it's only used within this scope, not cached. 
} 
else 
{ 
    // do something sensible (often nothing) if the object's already destroyed 
} 

這個成語的一個關鍵優點是強指針的作用域是,如果真塊,這有助於防止意外使用非初始化引用,或保存一個長期的強有力的參考呃比實際需要的。

相關問題