C ++ переопределяет переменную-член (std :: vector) - PullRequest
3 голосов
/ 15 января 2012

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

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 содержит дочерние узлы узла, и он не может иметь копию в производном классе, который содержит типизированную версию Nodes

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



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


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

1 Ответ

1 голос
/ 15 января 2012

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

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

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


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

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;
};

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

...