C++ 将唯一指针初始化为类成员

C++ 将唯一指针初始化为类成员,c++,smart-pointers,unique-ptr,C++,Smart Pointers,Unique Ptr,我正在研究一个树结构,它作为类成员具有一个向量唯一指针。在处理它时,我意识到如果唯一指针将拥有的对象作为参数出现,我不确定如何将唯一指针初始化为类成员 因此,我只是问:如果将拥有的对象作为参数出现,我应该如何将唯一指针初始化为类成员 我应该使用new(addTheObject(newobject()))然后使用std::make_unique?是否应将对象作为唯一对象传递(addTheObject(std::unique\u ptr&theObject))并使用std::move(theObje

我正在研究一个树结构,它作为类成员具有一个向量
唯一指针。在处理它时,我意识到如果唯一指针将拥有的对象作为参数出现,我不确定如何将唯一指针初始化为类成员

因此,我只是问:如果将拥有的对象作为参数出现,我应该如何将唯一指针初始化为类成员

我应该使用new(
addTheObject(newobject())
)然后使用
std::make_unique
?是否应将对象作为唯一对象传递(
addTheObject(std::unique\u ptr&theObject)
)并使用
std::move(theObject)

正确的处理方法是什么

如果您需要更具体的示例:

我有一个
dtu节点
类,它是树的一个节点,我将使用
dtu节点
构造一棵树

dtu节点
有一个名为
addChild()
的方法,用于将子节点插入其节点向量

DT_节点
将在不同的cpp文件中用于构造树,这意味着另一个cpp文件将使用
addChild()
方法添加节点的子节点

// DT_Node.hpp
class DT_Node
{
public:

    DT_Node();
    virtual ~DT_Node();

    virtual void decide() = 0;

    virtual void addChild( ??? );

private:

    std::vector< std::unique_ptr<DT_Node> > mNodes;
};
您需要的是:

void DT::Node::addChild(std::unique_ptr<DT_Node>&& child) {
    mNodes.emplace_back(std::move(child));
}
void DT::Node::addChild(std::unique\u ptr&&child){
mNodes.emplace_back(std::move(child));
}

顺便说一下,你的标题有误导性。unique_ptr不是一个成员(它包含在一个成员中),并且您也不是绝对没有初始化一个成员(为此,您将在构造函数中使用成员初始值设定项列表语法)

std::unique_ptr
保留指向对象的所有权。这意味着,如果要将其作为参数传递,则必须移动所有权

类似(注意
移动
&&
-参考):

void addChild(std::unique\u ptr&&iNode){
mNodes.emplace_back(std::move(iNode));
}
最后,我强烈建议你看看。
它为使用智能指针的数据结构提供了一些有用的建议。

假设DT_节点不是纯虚拟基类,这是代码片段。您还需要一个复制构造函数。使用了两个版本的addChild,这是不言自明的

  class DT_Node
{
public:    
    DT_Node();
    DT_Node(const DT_Node& other); // copy constructor will be needed
    virtual void addChild(std::unique_ptr<DT_Node>&& node); // move from source
    virtual void addChild(const std::unique_ptr<DT_Node>& node);  //non destructible source

private:    
    std::vector<std::unique_ptr<DT_Node> > mNodes;
};    

void DT_Node::addChild(std::unique_ptr<DT_Node>&& node) 
{
    mNodes.push_back(std::move(node));
}
void DT_Node::addChild(const std::unique_ptr<DT_Node>& node)  
{

    std::unique_ptr<DT_Node> new_node = std::make_unique<DT_Node>(*node);
    mNodes.push_back(std::move(new_node));
}
类dtu节点
{
公众:
DT_节点();
DT_节点(const DT_节点和其他);//将需要复制构造函数
虚拟void addChild(std::unique_ptr&&node);//从源移动
虚拟void addChild(const std::unique_ptr&node);//不可破坏源
私人:
std::向量mNodes;
};    
void DT_Node::addChild(std::unique_ptr&&Node)
{
mNodes.push_back(std::move(node));
}
void DT_Node::addChild(const std::unique_ptr&Node)
{
std::unique_ptr new_node=std::make_unique(*node);
mNodes.push_back(std::move(new_节点));
}

“作为参数提供”-你是什么意思?你的类不是一个带参数的模板,所示的构造函数也没有函数参数…?是的,我的意思是函数参数或参数
addChild
的第二个实现将以两个
unique\u ptr
拥有同一个对象而告终,当第二个实现尝试删除它时,它们将返回UB。您可以使用
node.release()
,但这绝对不是const member.Ah。不,我明白了。它正在调用复制构造函数。这段代码绝对不是自解释的。它非常需要注释。@MartinBonner:是的,第二个函数将启用创建新节点的功能,而不会破坏某些搜索树中所需的父节点。请注意,OP的成员变量名为
mNodes
,而不是
\u nodes
。第一句话是我的答案中缺少的关键一句。谢谢你的视频!很抱歉这个题目,我的动机是想让这个问题更一般化
void addChild(std::unique_ptr<Node>&& iNode) {
  mNodes.emplace_back(std::move(iNode));
}
  class DT_Node
{
public:    
    DT_Node();
    DT_Node(const DT_Node& other); // copy constructor will be needed
    virtual void addChild(std::unique_ptr<DT_Node>&& node); // move from source
    virtual void addChild(const std::unique_ptr<DT_Node>& node);  //non destructible source

private:    
    std::vector<std::unique_ptr<DT_Node> > mNodes;
};    

void DT_Node::addChild(std::unique_ptr<DT_Node>&& node) 
{
    mNodes.push_back(std::move(node));
}
void DT_Node::addChild(const std::unique_ptr<DT_Node>& node)  
{

    std::unique_ptr<DT_Node> new_node = std::make_unique<DT_Node>(*node);
    mNodes.push_back(std::move(new_node));
}