I'm facing a design issue in my program. I have to manage Nodes object which are part of a root ChainDescriptor.
Basically it looks like the following:
class ChainDescriptor
{
public:
~ChainDescriptor()
{
//delete the nodes in nodes...
}
void addNode(Node *);
Node * getNode();
const std::list<Node *>& getNodes() const;
std::list<Node *> m_nodes;
};
class Node
{
public:
Node(Node *parent);
void addChild(Node *node);
Node * getChild(const std::string& nodeName);
private:
Node * m_parent;
std::list<Node*> m_childs;
};
The ChainDescriptor class owns all the nodes and is responsible of deleting them. But these classes need now to be used in another program, a GUI with undo/redo capabilities, with the problematic of the "ownership". Before modifying the existing code in depth, I'm considering the different solutions:
shared_ptr
and respective list<shared_ptr<...> >
weak_ptr
and respective list<weak_ptr<...> >
In the example above, I don't really know where to use shared_ptr
and weak_ptr
properly.
Any suggestion?
You can use shared_ptr
for m_childs
and weak_ptr
for m_parent
.
However, it might be still reasonable to retain the raw pointer to the parent Node
and don't use any weak pointers at all. The safeguarding mechanism behind this is the invariant that non-null parent always exists.
Another option is using shared_ptr
in ChainDescriptor
only and retaining all raw pointers in Node
. This approach avoids weak pointers and has a clean ownership policy (parent nodes own their children).
Weak pointers will help you to manage the memory automatically, but the backside of this are fuzzy ownership logic and performance penalties.
shared_ptr
is owning smart pointer and weak_ptr
is referencing smart pointer.
So in your situation I think the ChainDescriptor
should use shared_ptr
(it owns the nodes) and Node
should use weak_ptr
for m_parent
(it only references it) and shared_ptr
for m_childs
(it owns them).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With