Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Replace raw pointers with shared and weak ptr

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:

  • using shared_ptr and respective list<shared_ptr<...> >
  • using 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?

like image 553
Zyend Avatar asked Feb 15 '23 16:02

Zyend


2 Answers

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.

like image 118
Sergey K. Avatar answered Feb 19 '23 20:02

Sergey K.


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).

like image 23
Johny Avatar answered Feb 19 '23 20:02

Johny