将唯一指针初始化为 Class 成员

Initializing Unique Pointers as a Class Member

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

所以,我只是问:如果将拥有的 object 作为参数,我应该如何将唯一指针初始化为 class 成员?

我应该使用新的(addTheObject(new Object()))然后使用std::make_unique吗?我应该将 object 作为 unique_ptr ( addTheObject(std::unique_ptr<Object>& theObject) ) 传递并使用 std::move(theObject)?

正确的处理方法是什么?

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

我有一个DT_Nodeclass,是一棵树的节点,我会用DT_Node.

构造一棵树

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

DT_Node会在不同的cpp文件中被用来构造一棵树,也就是说另一个cpp文件会使用addChild()的方式来添加节点的children。

// 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;
};

// DT_Node.cpp
DT_Node::DT_Node()
{

}

DT_Node::~DT_Node()
{
    mNodes.clear();
}

void DT_Node::addChild( ??? )
{
    ???
}

您需要的是:

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

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

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

类似于(注意 move&&-参考):

void addChild(std::unique_ptr<Node>&& iNode) {
  mNodes.emplace_back(std::move(iNode));
}

最后,强烈建议大家看一下this Herb Sutter Video。 它给出了一些关于使用智能指针的数据结构的有用建议。

假设 DT_Node 不是纯虚基 class ,这是代码片段。您还需要一个复制构造函数。使用了两个版本的 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));
}