如何深度复制shared_ptr?

问题描述 投票:0回答:2

我有一个简单的类Node树MultNode。 它是 Node.js 的子类。 _pRight 和 _pLeft 是 std::shared_ptr 对象。类节点是一个抽象类。 DerFun 对乘法节点进行导数函数。 我必须创建临时的左右节点(pTmpR 和 pTmpL),我只需要使用智能指针。我不知道如何创建 shrared_ptr 的深拷贝。

void MultNode::DerFun() {
        auto pTmpR =  _pRight;
        auto pTmpL = _pLeft;
        _pRight->DerFun();//sin(pi/4)*cos(pi/4); for checking
        _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);
    }
c++ boost stl smart-pointers
2个回答
2
投票

通过

Derived
指针深度复制
Base
不能由编译器完成,因为它不知道在编译时复制什么。

解决方案是制作一个虚拟

deepcopy
函数,它负责制作这个派生对象的深度复制,它将调用
deepcopy
它的所有子对象来构造一个真正的深度复制,因为它是在一个指针上调用的正确的函数将在运行时被调用。

#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) {};
};

1
投票

根本不需要深拷贝任何东西。你有共享的指针,利用它们来发挥你的优势。

这里是一个可以推导的最小系统。请注意,它构建的是 DAG,而不是树。一切都是

const
,什么都没有改变。节点尽可能共享。

#include <memory>

class Node;

using NodePtr = std::shared_ptr<const Node>;

using Number = double;

class Node
{
    public:
        virtual ~Node() = default;
        virtual NodePtr derive() const = 0;
};

class AddNode : public Node
{
    public:
        AddNode (const NodePtr& a, const NodePtr& b) : a(a), b(b) {}
    private:
        NodePtr a, b;
        NodePtr derive() const override 
        { 
            return std::make_shared<AddNode>(a->derive(), b->derive()); 
        }
};

class MultNode : public Node
{
    public:
        MultNode (const NodePtr& a, const NodePtr& b) : a(a), b(b) {}
    private:
        NodePtr a, b;
        NodePtr derive() const override
        {
            const auto l = std::make_shared<MultNode>(a, b->derive());
            const auto r = std::make_shared<MultNode>(a->derive(), b);
            return std::make_shared<AddNode>(l, r);
        }
};

class ConstNode : public Node
{
    public:
        ConstNode (Number v) : v(v) {}
    private:
        Number v;
        NodePtr derive() const override 
        { 
            return std::make_shared<ConstNode>(Number{0}); 
        }
};

class VarNode : public Node
{
    public:
        VarNode() {}
    private:
         NodePtr derive() const override 
         { 
             return std::make_shared<ConstNode>(Number{1}); 
         }
};

注意事项:

  1. 没有太多测试
  2. 仅支持一个变量(易于更改)
  3. 缺少许多有用的节点,例如除法、功能组合、幂、...(容易添加)
  4. 没有常数传播或其他方法来简化表达式(可以作为单独的方法添加)
© www.soinside.com 2019 - 2024. All rights reserved.