C++ переопределяет переменную-член (std::vector)

Вот классы, о которых мой вопрос

class Graph {}
class SceneGraph : public Graph {}

class Node {
public:
    virtual Node* getNode(int index) { return mNodeList[index]; }

protected:
    vector<Node*> mNodeList;
    Graph* mGraph;
}

class TransformationNode : public Node {
public:
    TransformationNode* getNode(int index) { return static_cast<TransformationNode*> (mNodelist[index]); }

    void _update() {
        auto beg = mNodeList.begin();
        auto end = mNodeList.end();
        while (begin != end) {
            TransformationNode* node = static_cast<TransformationNode*> (*beg);
            node->_update();
        }
    }

private:
    bool mUpdated;
    SceneGraph* mGraph;    
}

Прежде всего, я хочу поговорить о проблемах, которые я решил. Они могут помочь другим. И вы можете подтвердить мне, если я прав ^^

  1. Могу ли я переопределить функцию с другим типом возврата?
    Узел * getNode(int index) стал TransformationNode* getNode(int index)

    Да, если возвращаемые типы ковариантны: http://www.tolchz.net/?p=33

  2. Могу ли я переопределить член?

    Я не знаю о переопределении, но переменная с тем же именем в производном классе будет скрывать переменную в базовом классе

И есть проблема, я действительно хочу обойти некоторые, как

В классе TransformationNode я сделал много (ИМХО) преобразования типов из базового класса в производный. Я определенно знаю, что все элементы в векторе mNodeList являются TransformationNodes, но для обработки mNodeList я должен набрать приведение их.

Наследование правильно, я имею в виду TransformationNode - это узел

mNodeList содержит дочерние узлы узла и не может иметь копию в производном классе, который содержит типизированную версию узлов

И, наконец, я могу даже использовать reinterpered_cast, если static_cast более дорогой. Можете ли вы сообщить мне о стоимости этих операций? они действительно большие проблемы с производительностью?
assert (dynamic_cast)... меры предосторожности уже приняты.



Вкратце, я хочу, чтобы мой компилятор знал, что mGraph на самом деле является SceneGraph*, а mNodeList содержит TransformationNode *, что помогает мне избежать потери приведения типов.


Спасибо, что нашли время

1 ответ

1) правильно, вы действительно можете переопределить (виртуальные!) Базовые функции, если возвращаемый тип более производный.

Объявление 2): действительно, вы не можете "переопределить" участников. Перепроектируйте базовый класс, если вам нужно более гибкое переопределяемое поведение.

static_cast это статическая операция, которая разрешается во время компиляции, так же, как reinterpret_cast это не имеет никакой "стоимости".


Как предполагает @Seth в комментарии, это может быть опция для перемещения контейнера. Спросите себя, может ли быть когда-нибудь абстрактный Nodeили каждый узел на самом деле имеет какой-то производный конкретный тип? Возможно, вы могли бы сделать Node Аннотация:

struct Node { Node * getNode(size_t index) const = 0; };

struct TransformNode : Node
{
    TransformNode * getNode(size_t index) const { return m_nodes[index]; }
private:
    std::vector<TransformNode *> m_nodes;
};

Поместите весь интерфейс в базовый класс, но реализуйте его только в каждом конкретном классе.

Другие вопросы по тегам