移动后,unique_ptr变空

时间:2016-05-29 15:33:06

标签: c++

我第一次尝试使用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来获得预期的值,那么我怎么能用智能指针来做(生长一棵树)呢?

3 个答案:

答案 0 :(得分:2)

从物体移动后,它在概念上是空的。这就是为什么移动比复制更有效的原因,因为你可以窃取随后消失的资源。从一个对象移动两次而不给出是一个新值是一个错误。此外,unique_ptr拥有对象的唯一所有权,因此只能有一个,因此您无法将其传递给growTreeroot->children

要解决此问题,您必须决定谁拥有childstd::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调用后,原始对象现在处于有效但空状态(其他对象通常处于有效但未指定的状态,当然不是原始状态,并且再次使用)。 这是预期的,并且由于尝试再次使用它,您的代码会出错。