【问题标题】:Understanding exception safety of shared_ptr::void reset (U* p);了解 shared_ptr::void reset (U* p) 的异常安全;
【发布时间】:2015-11-17 12:17:52
【问题描述】:

我试图了解template <class U> void shared_ptr::reset (U* p); 函数的异常安全性。 In the documentation我发现了这个:

此外,调用此函数具有与 if 相同的副作用 shared_ptr 的析构函数在其值更改之前被调用(包括 如果此 shared_ptr 是唯一的,则删除托管对象)。

所以,我们可以假设析构函数不会抛出。但是如果operator new 抛出怎么办?那么我们将拥有shared_ptr 的什么状态?是否保持不变?

【问题讨论】:

标签: c++ shared-ptr


【解决方案1】:

根据 [util.smartptr.shared.mod],shared_ptr::reset(stuff) 的所有四个重载都完全等价于

shared_ptr(stuff).swap(*this)

如果构造 shared_ptr(stuff) 抛出(例如,如果分配新的控制块(或实现使用的任何等效机制)抛出),则 *this 不受影响,因为您永远不会到达 swap 和任何指针传入的stuff 被适当地删除(因为这是由shared_ptr 的构造函数保证的)。

swap 本身是 nothrow,交换后销毁临时的 shared_ptr 也是如此。

【讨论】:

  • 很好的答案。我可能会补充一点,stuff 的析构函数也必须是 noexcept
  • @AndyG 这是相应构造函数的规范所要求的,在 UB 的痛苦中。
【解决方案2】:

函数接受一个指针。这意味着 new 必须在执行进入函数之前完成。在函数内部,我假设只分配了一个指针和一些整数类型,而那些不会抛出。

【讨论】:

  • 共享指针应该分配内部存储(带计数器)。
猜你喜欢
  • 1970-01-01
  • 2021-11-18
  • 2016-08-05
  • 1970-01-01
  • 1970-01-01
  • 2016-06-16
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
相关资源
最近更新 更多