This is not really an answer, but another question about your design approach in general:
Apparently you're trying to design a tree node, right?
Why are you storing the parent class in the node and not vice versa (i.e. holding a std::vector
of the child node instances or pointers). This would simplify semantics for assignment (copying) a lot. You'll need methods to add/remove/clear child nodes in turn of course, setting the _parent
member should be done internally within add/remove implementation then. Tree leaf implementations of nodes would just provide empty methods for this functionality. Also I would add another level of indirection then and declare Node
as a pure abstract class and provide s.th. like ContainerNodeBase
and LeafNodeBase
as 1st level of implementation.
Also I would avoid using raw pointers in (at least) production code. You should use std::shared_ptr
or alike.
Let me give an example what I think your Node
design should look like:
1st Level provide abstract interfaces:
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() {}
};
2nd Level provide base implementation:
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_;
};
3rd Level provide concrete implementation(s)
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);
}
}