移动unique_ptr:重置源vs.销毁旧对象



我的问题是关于https://en.cppreference.com/w/cpp/memory/unique_ptr

中的例子
struct List
{
struct Node
{
int data;
std::unique_ptr<Node> next;
};

std::unique_ptr<Node> head;

~List()
{
// destroy list nodes sequentially in a loop, the default destructor
// would have invoked its `next`'s destructor recursively, which would
// cause stack overflow for sufficiently large lists.
while (head)
head = std::move(head->next);
}

...
};

head = std::move(head->next)时,有三件事发生:

  1. resethead->nexttonullptr;
  2. 设置head为新值;
  3. 销毁head用来指向的Node对象;

上面的代码工作意味着3保证发生在1之后,否则链接仍然存在

我想知道是否有一个书面的规则来保证这样的顺序,或者它只是一个隐藏的实现细节,例子只是工作。

head = std::move(head->next)时,有三件事发生:

  1. resethead->nexttonullptr;
  2. 设置head为新值;销毁head曾经指向的Node对象;

在这种情况下,赋值操作符应该像调用head.reset(head->next.release())函数一样工作,如[unique.ptr.single.asgn]/3:

constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;

Effects:调用reset(u.release())get_deleter() = std​::​forward<D>(u.get_deleter())

在这样的表达式中,head->next.release()必须首先求值。reset按以下顺序执行其工作:

  1. head->next.release()的结果赋值给存储指针
  2. 删除先前存储的指针的值

这个操作顺序也是标准的一部分,[unique.ptr.single.modifiers]/3:

constexpr void reset(pointer p = pointer()) noexcept;

效果:将p赋值给存储指针,然后使用存储指针的旧值old_pif (old_p) get_deleter()(old_p);求值


长话短说-你的理解是正确的,并有标准的保证

相关内容

  • 没有找到相关文章

最新更新