节点层次结构和继承

Node hierarchy and inheritance

本文关键字:继承 层次结构 节点      更新时间:2023-10-16

我制作了一个场景图层次结构,其中每个节点都有父节点和可能的子节点。我创建了这个BaseNode类

class BaseNode
{
public:
    BaseNode(const char *nodeName, BaseNode *parent);
    ~BaseNode();
    BaseNode* addChildSceneNode(const char *name);
    void deleteChildSceneNode(const char *name);
    void deleteAllChildSceneNodes();
    BaseNode* findFirstSceneNode(const char *name);
    BaseNode* getChildSceneNode(const char *name);
    BaseNode* getChildSceneNode(unsigned int index);
    void setName(const char *name);
    void setTranformation(const glm::mat4 &transformation);
    unsigned int getNumChildren() const { return _children.size(); }
    const char *name() const { return _name.c_str(); }
    BaseNode* parent() const { return _parent; }
    const glm::mat4& transformation() const { return _transformation; }
    const glm::mat4& toRootTransformation() const { return _toRoot; }
protected:
    std::string _name;
    glm::mat4 _transformation;
    glm::mat4 _toRoot;
    BaseNode *_parent;
    std::vector<BaseNode*> _children;
};

我有这个继承自BaseNode的SceneNode类

class SceneNode : public BaseNode
{
public:
    SceneNode(const char *nodeName, SceneNode *parent);
    ~SceneNode();
    void attachRenderMeshData(RenderMeshData *renderMeshData);
    const std::vector<RenderMeshData*>* renderMeshDatas() { return &_meshDatas; }
private:
    std::vector<RenderMeshData*> _meshDatas;
};

现在我的问题是关于所有包含BaseNode*参数的成员函数。

目前,当使用SceneNode对象时,我必须显式地将BaseNode*转换为SceneNode*,如下所示

SceneNode *mySceneNode = new SceneNode("root", nullptr);
mySceneNode->addChildSceneNode("my child");
SceneNode *child = reinterpret_cast<SceneNode*>(mySceneNode->getChildSceneNode("my child")); //i thought this should be dynamic_cast but the compiler throws an error.. weird

我的目标是拥有"多种类型"的BaseNode,这样我就不必每次都重写它的父/子功能。

你知道我怎样才能做得更好吗?

为什么不为您的BaseNode类使用模板?

这样就可以在不同类型的BaseNode之间使用通用代码。

例如,要生成SceneNode,可以生成BaseNode<SceneNode>

一个c++类模板的例子。


如果SceneNode继承BaseNode,您可以简单地将SceneNode赋值给BaseNode*类型,而不需要强制转换。您可能还需要调用基类的构造函数。

class SceneNode : public BaseNode {
public:
    SceneNode() : BaseNode("foo") {}
};

由此,如果调用s = new SceneNode,应该能够将s赋值给BaseNode*的集合,而不需要强制转换。