【问题标题】:weak_ptr - Dereferencing - Throw if expiredweak_ptr - 取消引用 - 如果过期则抛出
【发布时间】:2016-09-23 14:19:36
【问题描述】:

取消引用weak_ptr 不会自动检查指针是否已过期。为什么要这样设计?

我想安全地取消引用弱指针,而不必先使用expired() 检查它们,如果它们为空则抛出异常。

这是一个好的做法吗?什么是正确的做法?我是否应该重载 *-> 运算符以便他们首先执行此检查?我应该写一个免费的函数吗?

类似:

template< typename T >
weak_ptr< T > & check( weak_ptr< T > & p )
{
    if( p.expired() )
        throw logic_error( "Trying to dereference a null pointer." );
    return p;
}

然后:

weak_ptr< int > pi;
int i = *check( pi );

谢谢。

【问题讨论】:

  • 但是...你不能取消引用弱指针。你必须锁定它,从中获取一个共享的并使用它。
  • 您应该在访问原始指针之前从它们转换/创建一个 shared_ptr 以避免竞争条件。

标签: c++ pointers exception weak-ptr


【解决方案1】:

使用expired() 没有用处,因为它会在多线程程序中引入竞争。例外情况也不好,因为 weak_ptr 过期并不是什么例外:它们正是为此而设计的。

weak_ptr 的一个妙招是它们不可取消引用。相反,要访问您调用的对象lock(),它会自动返回指向该对象的shared_ptr,如果不可用,则返回null

访问弱指针的正常方式是:

void safe_do(weak_ptr<T> &w)
{
    shared_ptr<T> p = w.lock();
    if (p)
        p->do();
}

如果你真的想要异常,你可以使用这个变体:

void safe_do2(weak_ptr<T> &w)
{
    shared_ptr<T>(w)->do(); //throws a bad_weak_ptr if w expired
}

【讨论】:

  • 感谢您的回答。因此,如果我理解您所写的内容正确,那么尝试将 weak_ptr 转换为可以取消引用的 shared_ptr 的简单事实将在 weak_ptr expired 时抛出?在那种情况下,我不需要添加任何额外的检查,不是吗?
  • @Virus721 不,它会创建一个 NULL shared_ptr,然后您可以对其进行测试。
  • @RichardCritten 谢谢。所以我要做的是编写一个函数,该函数接受由 lock() 给出的 shared_ptr,如果它为 null,则抛出异常,然后返回相同的 shared_ptr,然后可以安全地取消引用,对吧?编辑是的,这基本上就是答案所说的,除了safe_do方法执行调用而不是返回检查的shared_ptr。对不起。
  • 实际上,shared_ptr(weak_ptr &amp;) 构造函数如果过期就会抛出。 weak_ptr::lock() 函数将返回 null。
猜你喜欢
  • 1970-01-01
  • 2018-08-27
  • 1970-01-01
  • 2023-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-03
  • 1970-01-01
相关资源
最近更新 更多