2010-05-17 62 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 
} 

这个成语的一个关键优点是强指针的作用域是,如果真块,这有助于防止意外使用非初始化引用,或保存一个长期的强有力的参考呃比实际需要的。

相关问题