공유 포인터로 자식 목록을 포함하는 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)
{}
그래서 나는 TreeNode를 얻을 그것으로 트리의 생성자를 호출하려고하는 서브 트리를 만들 수 있습니다.
shared_ptr<TreeNode> treeNode = oldTree->getASpecialNode();
shared_ptr<Tree> newTree = make_shared<Tree>(treeNode);
지금 newTree
의 루트는 treeNode
입니다. 하지만 문제는 모든 TreeNode가 부모를 가리키고 있다는 것입니다. treeNode
도 마찬가지입니다. newTreeNode
자체가 부모를 가지고 있기 때문에
weak_ptr<TreeNode> TreeNode::getParent() const
{
return parent;
}
newTree
의 모든의 TreeNode의 부모를 통과하여 루트를 계산
newTreeNode
아닌 다른 루트 노드에 도달합니다.
개체를 공유하고 원본 트리에서이 개체가 필요하므로 해당 부모를 삭제하는 것은 해결책이 아닙니다. 그래서 내가 볼 수있는 유일한 해결책은 TreeNode를 복사하고 모든 구성원을 복사하는 것입니다.
어떻게하면됩니까?
std::shared_ptr<TreeNode> TreeNode::clone() const
{
auto clone = new TreeNode (*this);
clone->setParent(weak_ptr<TreeNode>());
return shared_ptr<TreeNode>(clone);
}
하지만 여전히 부모를 계산하는 것은 원래의 루트 노드로 이어질 것입니다 : 다른 답변을 바탕으로
그래서이 시도. 그래서 하위 트리를 만들 수 없었습니다.
Tree
과 TreeNode
에 shared_ptr
을 사용하는 것은 잘못되었지만 내 코드가 아닙니다. 난 그냥 기능을 추가해야합니다. 전체 서브 트리가 복제 될 수있다
std::shared_ptr<TreeNode> TreeNode::clone() const
{
auto res = std::make_shared<TreeNode>();
for (auto child : *children) {
res->AddChild(child->clone());
}
return res;
}
복제본은 새로운 복사본을 만들어야합니다. 즉, 새 노드를 만들고 각 자식을 복제해야합니다. – Jarod42
제목에 "copy"라는 단어가 있기 때문에 지금까지 가지고있는 대답은 사본을 원한다고 합리적으로 추측합니다. 다른 경우 하위 트리는 기존 노드의 일부 (필터링 된 버전의 기존 트리)로 구성된 트리를 참조 할 수도 있습니다. 이러한 종류의 하위 트리는 자식 벡터에 대한 공유 포인터의 이점을 얻을 수 있습니다. 그래서 이것이 공유 포인터를 사용하는 이유입니다.하지만 이것이 요구 사항이 아니라면 shared_ptrs가 이상하게 보일 것입니다. – ROX
그 종류의 하위 트리를 선호한다고 생각합니다. 하지만 부모님 한테 문제가 생길거야. 코드 노드의 어딘가에 부모를 통과해야합니다. 그런 다음 원래 루트 노드로 이동합니다. – Sadik