这不是一个真正的答案,而是关于您的设计方法的另一个问题:
显然你正在尝试设计一个树节点,对吧?
为什么将父类存储在节点中而不是相反(即持有std::vector
子节点实例或指针)。这将大大简化分配(复制)的语义。当然,您需要依次添加/删除/清除子节点的方法,然后设置_parent
成员应该在添加/删除实现内部完成。节点的树叶实现只会为此功能提供空方法。另外我会添加另一个级别的间接并声明Node
为纯抽象类并提供s.th。喜欢ContainerNodeBase
和LeafNodeBase
作为第一级实施。
此外,我会避免在(至少)生产代码中使用原始指针。你应该使用std::shared_ptr
或类似的。
让我举个例子,我认为你的Node
设计应该是什么样子:
第一级提供抽象接口:
struct INode
{
virtual const std::string & name() const = 0;
virtual void name(const std::string& value) = 0;
virtual INode* parent() const = 0;
virtual ~INode() {}
};
struct INodeCotainer
{
virtual void add(std::shared_ptr<INode> child) = 0;
virtual void remove(const INode* child) = 0;
virtual void clear() = 0;
virtual const std::vector<std::shared_ptr<INode>>& childs() const = 0;
virtual ~INodeCotainer() {}
};
2级提供基础实现:
class NodeBase
: public INode
{
public:
virtual const std::string & name() const { return name_; }
virtual void name(const std::string& value) { name_ = value; }
virtual INode* parent() const { return parent_; }
protected: // protect this class from direct instantiation
NodeBase() {}
NodeBase(const NodeBase& rhs) { parent_ = nullptr; name_ = rhs.name; }
NodeBase& operator=(const NodeBase& rhs)
{
if(&rhs != this)
{
parent_ = nullptr; name_ = rhs.name;
}
return *this;
}
INode* parent_;
private:
std::string name_;
};
第三级提供具体实施
class ContainerNode
: public NodeBase
, public INodeContainer
{
public:
ContainerNode() : NodeBase {}
ContainerNode(const ContainerNode& rhs) : NodeBase(rhs)
{
std::copy(childs_,rhs.childs_);
}
ContainerNode& operator=(const ContainerNode& rhs)
{
NodeBase::operator=(rhs);
childs_.clear();
std::copy(childs_,rhs.childs_);
}
virtual void add(std::shared_ptr<INode> child)
{
childs_.push_back(child);
childs_.back()->parent_ = this;
}
virtual void remove(const INode* child)
{
// Find the child reference in the childs_ vector remove it
// and set it's parent_ member to nullptr
}
virtual void clear() { childs_.clear(); }
virtual const std::vector<std::shared_ptr<INode>>& childs() const
{ return childs_; }
private:
std::vector<std::shared_ptr<INode>> childs_;
}
class LeafNode
: public NodeBase
{
public:
LeafNode() : NodeBase {}
LeafNode(const LeafNode& rhs) : NodeBase(rhs) {}
LeafNode& operator=(const LeafNode& rhs)
{
NodeBase::operator=(rhs);
}
}