复制包含共享指针列表的共享指针后面的对象

复制包含共享指针列表的共享指针后面的对象

问题描述:

我有一个shared_ptr<Tree> tree和一个shared_ptr<TreeNode> node,其中包含儿童中的列表作为共享指针。复制包含共享指针列表的共享指针后面的对象

class TreeNode 
{ 
protected: 
    std::weak_ptr<TreeNode> parent; 

    /** 
    A list containing the children of this node 
    */ 
    std::shared_ptr<std::vector<std::shared_ptr<TreeEdge>>> children; 

    ... 

树只需要被赋予一个TreeNode作为它的根。

Tree::Tree(const shared_ptr<TreeNode> root) 
    : root(root) 
{} 

所以创建子树我试图让一个树节点,并调用树构造它。

shared_ptr<TreeNode> treeNode = oldTree->getASpecialNode(); 
shared_ptr<Tree> newTree = make_shared<Tree>(treeNode); 

现在的newTree根源是treeNode。但问题是,每个TreeNode都指向它的父节点。那么treeNode

weak_ptr<TreeNode> TreeNode::getParent() const 
{ 
    return parent; 
} 

当在newTree通过任何树节点的父母一起去计算的根,我们会达到一个不同的根节点比newTreeNode,因为newTreeNode本身具有父。

删除父项并不是解决方案,因为该对象是共享的,我们将在原始树中使用它。所以我看到的唯一解决方案是复制TreeNode并复制它的所有成员。

我该怎么做?

基于其他的答案,所以我尝试这样的:

std::shared_ptr<TreeNode> TreeNode::clone() const 
{ 
    auto clone = new TreeNode (*this); 
    clone->setParent(weak_ptr<TreeNode>()); 
    return shared_ptr<TreeNode>(clone); 
} 

但仍在计算的父母会导致原来的根节点。所以我无法创建一个子树。

我的感觉是shared_ptr用于TreeTreeNode,但它不是我的代码。我只需要添加一个功能。

+0

您的克隆应执行深层复制:创建一个新节点并克隆每个孩子。 – Jarod42

+0

由于您的标题包含“复制”这个词,因此您迄今为止的答案已经相当合理地假设您想要一个副本。在其他情况下,子树也可以指由一些现有节点组成的树(如现有树的过滤版本)。这种子树将从共享的指向儿童矢量的指针中受益。所以这就是它使用共享指针的原因,但如果这不是要求,那么我会同意shared_ptrs看起来很奇怪。 – ROX

+0

我想我更喜欢那种子树。但是我会遇到父母的问题。代码节点中的某处需要通过父节点遍历。然后可以转到原始根节点。 – Sadik

的整个子树已被克隆,而不仅仅是子根。由于没有任何指针被复制,所以复制初始化克隆没有用处。另外,为了保证强大的异常安全性,您应该避免使用裸指针分配内存。

未经测试的例子:

std::shared_ptr<TreeNode> TreeNode::clone() const 
{ 
    auto clone = std::make_shared<TreeNode>(); 
    clone->children->reserve(children->size()); 
    for(const auto& c : *children) { 
     auto c_clone = c->clone(); 
     c_clone->setParent(clone); 
     clone->children->push_back(c_clone); 
    } 
    return clone; 
} 

我有一个是错误的使用shared_ptrTreeTreeNode

份额你的感觉的感觉。当然,当节点具有父指针时,不清楚如何在多棵树上合理地共享节点。

std::shared_ptr<std::vector<std::shared_ptr<TreeEdge>>>也似乎过度间接。

+0

你忘了设置新的孩子的父母。 – Jarod42

+0

@ Jarod42好点;补充说。 – user2079303

+0

谢谢,这真的帮了我 – Sadik

你的克隆功能看起来应该是这样的:

std::shared_ptr<TreeNode> TreeNode::clone() const 
{ 
    auto res = std::make_shared<TreeNode>(); 

    for (auto child : *children) { 
     res->AddChild(child->clone()); 
    } 
    return res; 
}