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