【问题标题】:Can I get a raw pointer from boost's weak_ptr?我可以从 boost 的weak_ptr 中得到一个原始指针吗?
【发布时间】:2010-05-17 14:32:50
【问题描述】:

是否可以从 boost::weak_ptr 获取原始指针? Boost 的 shared_ptr 有 get() 方法和“->”操作符。 weak_ptr 没有相同的功能背后是否有一些理由?

【问题讨论】:

    标签: c++ boost shared-ptr smart-pointers weak-references


    【解决方案1】:

    weak_ptr 拥有一个非拥有引用,因此它所引用的对象可能不再存在。使用 weak_ptr 持有的原始指针本质上是危险的。

    正确的方法是使用weak_ptr::lock()weak_ptr 提升为shared_ptr 并从中获取指针。

    Boost weak_ptr documentation 解释了为什么将get() 功能作为weak_ptr 的一部分提供是不安全的,并提供了可能导致问题的代码示例。

    【讨论】:

    • 就此而言,如果你得到一个 shared_ptr 的原始指针,那么你可能会留下一个悬空指针,该指针随后也会被销毁......在多线程的情况下,你甚至可以留下一个悬空指针代码运行中的指针if (!weak.expired()) weak->run();作为指向的对象可能在测试和方法执行之间被破坏(我想方法本身已正确同步)...
    • @Matthieu:当然你可以,就像如果你明确地delete一个对象但保留一个指向它的指针,你可能会留下一个悬空指针。必须将weak_ptr 提升为shared_ptr 的关键在于,它鼓励您按照您通常用于shared_ptr::get 的规则正确限定原始指针的使用范围。没有等效的方法可以正确地确定直接从 weak_ptr 获得的原始指针的使用范围。
    【解决方案2】:

    这是一个老问题,接受的答案很好,所以我不愿发布另一个答案,但似乎缺少的一件事是一个很好的惯用用法示例:

    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
    }
    

    这个习惯用法的一个关键优势是强指针的作用域是 if-true 块,这有助于防止意外使用未初始化的引用,或者保持强引用比实际需要的时间长。

    【讨论】:

      【解决方案3】:

      在获取原始指针之前,您首先需要从weak_ptr 派生出shared_ptr。

      你可以调用lock来获取shared_ptr,或者shared_ptr构造函数:

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

      【讨论】:

      • 正如所写,这是不安全的 - 如果在临时 shared_ptr 被销毁时删除对象,您可能会留下一个悬空指针。只要您使用原始指针,就应该一直持有shared_ptr
      猜你喜欢
      • 2013-10-09
      • 1970-01-01
      • 2017-05-06
      • 2015-01-02
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 1970-01-01
      • 2018-07-19
      相关资源
      最近更新 更多