C++ 唯一\u ptr在移动后变为空

C++ 唯一\u ptr在移动后变为空,c++,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)

我第一次尝试使用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));
    }
    }
void growTree(唯一根){
//做一些计算
root->value=“一些值”
对于(int i=0;ichildren.push_back(move(child));
}
}
但是,我发现指针“child”在我将其推回
根->子对象之前变为空。为什么它在递归后会丢失其值?我在这里做错了什么?谢谢


EDIT1:现在我意识到我不能在移动后使用unique(唯一)ptr来获取期望值,那么我如何使用智能指针来实现(生长一棵树)?

当你将某个对象移动到其他对象时,你不再从该对象中移动该对象。你为什么期望这样

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

从对象中移动后,概念上它是空的。这就是为什么移动比复制更有效,因为您可以窃取随后消失的资源。从对象中移动两次而不给出新值是一个错误。此外,
唯一\u ptr
h作为对象的唯一所有权,因此只能有一个,因此不能将其同时传递给
growTree
root->children


要解决此问题,您必须决定谁拥有
子项
std::move
子项,并在另一个位置保留对该位置的稳定引用。如果该位置依赖于运行时,您可以使用
共享\u ptr

这非常正常:

推回之前
,您正在使用
std::move
移动
child
。它的字面意思是您将
child
赠送给
growTree
,您不再需要它了

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


如果要修改
子项
,应将其作为引用传递,以便
growTree
可以修改
节点
子项
指向的,而
子项
不会丢失指向它的指针:

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

如果你把唯一的东西移到另一只手上,它就不再在一只手上了。这看起来像是在按计划工作。
growTree(move(child))
确实让child空了,那么为什么它在下一行不是空的呢?“unique\u ptr在移动后变为空”-Yeees。你对唯一的\u ptr还有什么期待??“有效但不确定的状态”——“代码> UnQuyJPTR <代码>的状态在它被移动之后不是不确定的,它是NULL,您可以自由使用它。”标准Benjamin Lindley说,“我引用了”C++标准库中定义的类型对象可以从(12.8)移动。.可以显式指定或隐式生成移动操作。除非另有规定,否则从对象移动的操作应处于有效但未指定的状态。“。例如,CPPFREFERENCE使用的术语是有效的但未指定的状态,其解释为,只有没有先决条件的函数(如赋值运算符)才能在对象移动后安全地在对象上使用from@JesperJuhl:准确地说,“除非另有规定”.它是在20.10.1/4中为
唯一\u ptr
指定的--注意编辑,它是第20章,而不是2@Benjamin林德利,我的错。它是空的,我错过了。