【问题标题】:Node hierarchy and inheritance节点层次结构和继承
【发布时间】:2015-08-31 14:10:44
【问题描述】:

我制作了一个场景图层次结构,其中每个节点都有一个父节点,也可能有子节点。我创建了这个 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,因此我不必每次都重写其父/子功能。

知道如何才能做得更好吗?

【问题讨论】:

  • 你有一个没有单个虚函数的基类(甚至没有析构函数)。这是完全错误的,并且很可能会在您的程序中产生未定义的行为。您需要阅读面向对象这些词的含义,它们与多态性继承的关系,以及这些概念是如何实现的在带有虚函数的 C++ 中。
  • @n.m.这也是他为什么 dynamic_cast 给他错误的原因 - @Pilpel 你应该使用 static_cast 来上载你知道具有某种专业化的节点(dynamic cast 用于那些你无法确定的节点) - reinterpret_cast一旦你使用虚函数就会破坏你的代码。
  • 我明白了。谢谢(你的)信息。不过,这仍然不能回答我的问题
  • @BeyelerStudios 不,他应该使用 ANY 演员表。
  • @n.m. iff 你对场景图中的每种类型强制执行每个操作是

标签: c++ oop inheritance polymorphism


【解决方案1】:

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

这样你就可以在不同类型的 BaseNode 之间有共同的代码。

例如,要创建SceneNode,您可以使用BaseNode&lt;SceneNode&gt;

An example on C++ class templates.


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

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

因此,如果您调用 s = new SceneNode,您应该能够将 s 分配给 BaseNode* 的集合而无需强制转换。

【讨论】:

  • 这让我的代码看起来更笨拙...有没有不同的解决方案?
  • 尝试将您的孩子存储为BaseNode 类型,这样您就不必执行reinterpret_cast。如果所有类型都继承BaseNode,则指向SceneNode 的指针可以保存在BaseNode* 类型的数组(或集合)中。
  • 您的意思是 std::vector 而不是 std::vector?如果是这样,我不喜欢它。我更喜欢将指针存储在向量中,以避免在向量重新分配时复制对象的所有数据成员。
  • 不,我的意思是像std::vector&lt;BaseNode*&gt;
  • 您不需要reinterpret_cast 来从继承的类型中分配基指针。
猜你喜欢
  • 2011-06-16
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多