我的问题是关于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.将head->next
重置为nullptr
;
1.将head
设置为新值;
1.销毁head
所指向的Node对象;
上面的代码工作意味着3保证发生在1之后,否则链接仍然存在。
我想知道是否有一个写下来的规则来保证这样的秩序,或者它只是一个隐藏的实现细节和例子只是工作。
1条答案
按热度按时间uubf1zoe1#
当
head = std::move(head->next)
时,会发生三件事:1.将
head->next
重置为nullptr
;1.将
head
设置为新值;1.销毁head所指向的Node对象;
在这种情况下,赋值运算符应该像调用
head.reset(head->next.release())
函数一样工作,按照[unique.ptr.single.asgn]/3:效果:调用
reset(u.release())
,然后调用get_deleter() = std::forward<D>(u.get_deleter())
。在这样的表达式中,
head->next.release()
无论如何都必须首先计算。reset
按以下顺序执行其工作:1.将
head->next.release()
的结果分配给存储的指针1.删除指针以前存储的值
这种操作顺序也是标准的一部分,[unique.ptr.single.modifiers]/3:
效果:将p分配给存储指针,然后使用存储指针的旧值
old_p
计算if (old_p) get_deleter()(old_p);
长话短说-您的理解是正确的,并得到标准的保证