Search code examples
c++booststlsmart-pointers

How to make deep a copy of shared_ptr?


I have a simple class of Node tree MultNode. It's subclass of Node. _pRight and _pLeft are std::shared_ptr<Node> objects. Class Node is an abstract class. MultNode::DerFun() performs derivative function for multiplication Node.

\frac{d}{dx}[f(x)g(x)]=f(x)g'(x)+f'(x)g(x)

I have to create temporary right and left Node(pTmpR and pTmpL) and I need use only smart pointers. I have no idea how to create deep copy of shrared_ptr.

void MultNode::DerFun() {
    auto pTmpR =  _pRight;
    auto pTmpL = _pLeft;
    _pRight->DerFun(); // sin(pi/4) * cos(pi/4);
    _pLeft->DerFun();  // der(sin(pi/4) * cos(pi/4));
    _pRight = std::make_shared<AddNode>(
        std::make_shared<MultNode>(_pRight, pTmpL),
        std::make_shared<MultNode>(pTmpR, _pLeft));
    _pLeft = std::make_shared<NumNode>(1);
}

Solution

  • deep copying a Derived by a Base pointer cannot be done by the compiler because it won't know what to copy at compile-time.

    the solution is to make a virtual deepcopy function, which is responsible for making a deepcopy of this derived object, which will call deepcopy on all of its children to construct a true deepcopy, and since it is called on a pointer the correct function will be called at runtime.

    #include <memory>
    
    class Node {
    public:
        virtual std::shared_ptr<Node> deepcopy() const = 0;
        virtual ~Node() = default;
    };
    
    class MultNode: public Node {
    private:
        std::shared_ptr<Node> m_pleft;
        std::shared_ptr<Node> m_pright;
    public:
        virtual std::shared_ptr<Node> deepcopy() const
        {
            return std::make_shared<MultNode>(m_pleft->deepcopy(), m_pright->deepcopy());
        }
        MultNode(std::shared_ptr<Node> pleft, std::shared_ptr<Node> pright) : 
            m_pleft(pleft), m_pright(pright) {};
    };