节点层次结构继承,创建和返回类型混淆

时间:2012-03-29 07:22:48

标签: c++ inheritance nodes

大家好日子。

假设我有这样的节点层次结构。

class Node
{
public:
    Node (Node* parent, const std::string &name) :
             parent(0), name(name)
    {
        if (parent)
            parent->AddChild(this);
    }
    virtual ~Node ()  { ......... }

    virtual Node* CreateChild (const std::string& name);   // 
    virtual Node* GetChild (const std::string& name) // <--- 

    Node* parent;
    std::string name;
    std::unordered_map<std::string, Node*> children;
};

class SceneNode : public Node
{
public:
    SceneNode (Node *parent, const std::string &name) :
            Node(parent, name), id(1)   { }
    virtual ~SceneNode ()  {  }
    // all scenenode stuff like seting rotatin, position and so on
    ..................................

    virtual void Render () = 0;
    virtual void ShowBoundingBox () = 0;

    int id;
};

class SceneSphereNode : public SceneNode
{
public:
    SceneSphereNode (Node *parent, const std::string &name) :
                             SceneNode (parent, name)   {  }
    virtual ~SceneSphereNode ()  { }

    void GetModel ()
    {
        std::cout << "getting model \n";
    }

    void ShowBoundingBox ()  { }
    void Render ()
    {
        std::cout << "Doing sphere render \n";
    }
};

class SceneManager
{
public:
    std::unordered_map<std::string, Node*> staticNodes;

    SceneManager () {}
    virtual ~SceneManager ()
    {
     // delete static nodesnodes   
    }
    ..........................................
    SceneNode* GetNode (const std::string &name)
    {
        // whatever whenever ............ some code
        Node *someNode = // it calls Node::GetChild     
        return dynamic_cast<SceneNode*>(someNode);      
    }

};

PS:代码可能无法正常工作,只是为了表明问题的想法。

主要问题是我希望有一个“通用”Node类,可用于小部件,xml等。我不想把从SceneNode那里挖出麻烦的东西给Node(实际上可以通过创建Node而不是sceneNode来解决问题)。但问题就出现了。

让我们说SceneManager已经有了一些对象,我想得到一个:

SceneManager manager;
SceneNode* node1 = new SphereNode ("Node1", manager.GetRootNode());
manager.GetNode("Node1");  // <-- there ??? :(

它返回Node*,我必须dynamic_castSceneNode*。但是因为它的一个场景管理器以及很多渲染的东西都在那里(那个dynamic_cast)的东西可能非常令人畏惧,而且不知何故我觉得我的内心并不是那么聪明。

你能解决我应该解决的问题,也许采取一些不同的方法。

对不起我的英语技能很低,谢谢你的建议。

2 个答案:

答案 0 :(得分:1)

首先,我不会尝试将许多不相关的概念转化为一个类,即XML节点与场景节点是完全不同的,并且从同一个基础派生它们很少获得。 dynamic_cast可能非常昂贵,但可以使用一些技术:

  • 如果演员的目标总是与节点完全相同(即,您只存储叶子),那么可以只用typeid()来检查。
  • 如果失败的dynamic_cast被视为错误条件,那么您可以坚持dynamic_cast进行调试&amp;内部版本构建,但使用static_cast作为候选版本。这样的强制转换或多或少只是一个自由模板函数,它包裹了强制转换,并包含#ifdef dynamic_caststatic_cast

答案 1 :(得分:1)

您还可以考虑visitor模式,从而消除对dynamic_cast的需求。

http://en.wikipedia.org/wiki/Visitor_pattern