共有ポインターとして子リストを含む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;
...
AツリーはそのルートとしてのTreeNodeを付与する必要があります。
Tree::Tree(const shared_ptr<TreeNode> root)
: root(root)
{}
したがって、そのサブツリーを作成するには、私はTreeNodeを取得し、それを使ってTreeコンストラクタを呼び出します。
shared_ptr<TreeNode> treeNode = oldTree->getASpecialNode();
shared_ptr<Tree> newTree = make_shared<Tree>(treeNode);
今newTree
のルートはtreeNode
です。しかし、問題は、すべてのTreeNodeがその親を指していることです。それでtreeNode
もそうです。 newTree
内の任意のTreeNodeの両親を経てルートを計算する場合newTreeNode
自身が親を持っているので
weak_ptr<TreeNode> TreeNode::getParent() const
{
return parent;
}
、我々は、newTreeNode
とは異なるルート・ノードに到達します。
オブジェクトが共有されているため、その親を削除することは解決できません。元のツリーにそのオブジェクトが必要になるためです。だから、私が見る唯一の解決策は、TreeNodeをコピーして、それがすべてのメンバーをコピーすることです。
どうすればいいですか?
std::shared_ptr<TreeNode> TreeNode::clone() const
{
auto clone = new TreeNode (*this);
clone->setParent(weak_ptr<TreeNode>());
return shared_ptr<TreeNode>(clone);
}
しかし、まだ両親を計算すると、元のルートノードにつながる:SO私はこれを試した上で、他の回答に基づいて
。だから私はサブツリーを作ることができませんでした。
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
あなたのタイトルには「コピー」という単語が含まれているので、これまでの回答ではコピーが必要です。他の場合には、サブツリーは、既存のツリーのフィルタリングされたバージョンのような、いくつかの既存のノードからなるツリーを参照することもできる。そのような種類のサブツリーは、子どものベクトルへの共有ポインタから利益を得ます。だからそれが共有ポインタを使う理由ですが、それが要件でないならば、shared_ptrsは奇妙に見えることに同意します。 – ROX
私はそのような種類のサブツリーを好むと思います。しかし、私は親のものに問題があります。コードノードのどこかで、親を通して移動する必要があります。次に、元のルートノードに移動します。 – Sadik