unique_ptr移动后变得空

unique_ptr becomes empty after moving

本文关键字:移动 ptr unique      更新时间:2023-10-16

我第一次尝试使用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));
    }
    }

但是,我发现指针"孩子"在我将它们推回root->children之前变为空。为什么它在递归后会失去其值?我在这里做错了什么?谢谢!

编辑1:现在我意识到我不能在移动它后使用unique_ptr来获得预期值,那么我如何使用智能指针来做到这一点(种植一棵树)呢?

这是完全正常的:

push_back之前,您正在移动childstd::move。从字面上看,这意味着您正在将child赠送给growTree,您不再想要它了。

移动后,child不再指向原始对象(因为另一个对象具有指向它的指针,所以您毕竟移动了它)。


如果要修改child,则应将其作为引用传递,以便growTree可以修改Node child指向,而不会使child丢失指向它的指针:

void growTree(std::unique_ptr<Note>& node);

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

要解决此问题,您必须决定谁拥有childstd::move孩子在那里,并在另一个地方保持对那个地方的稳定引用。如果该地点依赖于运行时,则可以改用shared_ptr

当你把东西搬给别人时,你就不再有搬出的东西了。你为什么会期待呢?

将unique_ptr移动到 growTree 调用中后,原始对象现在处于有效但为空的状态(其他对象通常处于有效但未指定的状态,当然不是原始状态,不应再次使用)。这是意料之中的,并且由于尝试再次使用它,您的代码有问题。