我第一次尝试使用unique_ptr来扩展二叉树,基本上如下所示:
void growTree(unique_ptr<Node> root){
//do some calculations
root->value = "some value"
for(int i=0;i<2;i++){
unique_ptr<Node> child(new Node);
growTree(move(child));
root->children.push_back(move(child));
}
}
然而,我发现指针&#34;孩子&#34;在我将它们推回root->children
之前变空。为什么它在递归后会丢失它的值?我在这做错了什么?谢谢!
EDIT1:现在我意识到在移动它之后我无法使用unique_ptr来获得预期的值,那么我怎么能用智能指针来做(生长一棵树)呢?
答案 0 :(得分:2)
从物体移动后,它在概念上是空的。这就是为什么移动比复制更有效的原因,因为你可以窃取随后消失的资源。从一个对象移动两次而不给出是一个新值是一个错误。此外,unique_ptr
拥有对象的唯一所有权,因此只能有一个,因此您无法将其传递给growTree
和root->children
。
要解决此问题,您必须决定谁拥有child
。 std::move
那里的孩子,并在另一个地方保持对该地方的稳定参考。如果该地点依赖于运行时,则可以改为使用shared_ptr
。
答案 1 :(得分:2)
这是完全正常的:
在push_back
之前,您正在使用child
移动std::move
。它实际上意味着您将child
赠送给growTree
,您不再需要它了。
移动后,child
不再指向原始对象(因为另一个对象有指向它的指针,你毕竟移动了它。)
如果您要修改child
,则应将其作为参考传递,以便growTree
可以修改Node
child
指向,child
没有丢失指向它的指针:
void growTree(std::unique_ptr<Note>& node);
答案 2 :(得分:1)
当你向其他人移动东西时,你不再拥有移动的东西。为什么你会这么想?
将unique_ptr移动到growTree调用后,原始对象现在处于有效但空状态(其他对象通常处于有效但未指定的状态,当然不是原始状态,并且不再次使用)。 这是预期的,并且由于尝试再次使用它,您的代码会出错。