Наследование иерархии узлов, создание и путаница возвращаемого типа - PullRequest
0 голосов
/ 29 марта 2012

Доброго всем дня.

Допустим, у меня есть такая иерархия узлов.

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_cast до SceneNode*. Но так как там работает sceneManager и много чего с рендерингом (этот dynamic_cast), то это может сильно снизить производительность, и почему-то я чувствую, что что-то там не очень умное.

Можете ли вы подсказать, что я должен исправить, возможно, используйте другой подход.

Извините за низкий уровень владения английским и благодарю вас за советы.

Ответы [ 2 ]

1 голос
/ 29 марта 2012

Вы также можете рассмотреть шаблон visitor, который устраняет необходимость в dynamic_cast.

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

1 голос
/ 29 марта 2012

Прежде всего, я бы не пытался объединить многие несвязанные концепции в один класс, т. Е. Узлы XML - это нечто совершенно иное, чем узлы сцены, и очень мало было получено извлечь их из одной и той же базы.dynamic_cast может быть очень дорогостоящим, но есть несколько методов, которые можно использовать:

  • Если цель приведения всегда имеет тот же тип, что и узел (т. е. вы храните только листья), товместо этого можно просто проверить с помощью typeid().
  • Если неудачный dynamic_cast считается ошибочным условием, тогда вы можете придерживаться dynamic_cast для сборок отладки и внутреннего выпуска, но используйте static_cast дляосвободить кандидатов.Такое приведение будет более или менее просто бесплатной функцией шаблона, которая упаковывает приведение и содержит #ifdef в dynamic_cast или static_cast.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...