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

copy object behind shared pointer containing a list of shared pointers

本文关键字:指针 共享 对象 列表 包含 复制      更新时间:2023-10-16

我有一个 shared_ptr<Tree> tree和一个包含儿童列表的CC_1作为共享指针。

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

因此,要创建那个子树,我尝试获取一个treenode并用它调用树构造函数。

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中的任何treenode的父母来计算根部时,我们将达到与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是错误的,但这不是我的代码。我只需要添加一个功能。

必须克隆整个子树,而不仅仅是子根。由于没有任何指针被复制,因此复制初始化克隆没有用。另外,您应该避免向分配记忆的裸露指针,以确保强大的例外安全性。

未经测试的示例:

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_ptr用于TreeTreeNode

是错误的

i 分享您的感觉。当然,当节点有父母指针时,尚不清楚如何在多个树上明智地共享节点。

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

您的克隆功能应该看起来像:

std::shared_ptr<TreeNode> TreeNode::clone() const
{
    auto res = std::make_shared<TreeNode>();
    for (auto child : *children) {
        res->AddChild(child->clone());
    }
    return res;
}