我有一个简单的类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);
}
通过
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) {};
};
根本不需要深拷贝任何东西。你有共享的指针,利用它们来发挥你的优势。
这里是一个可以推导的最小系统。请注意,它构建的是 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});
}
};
注意事项: