C ++重写成员变量(std :: vector)

时间:2012-01-14 23:49:36

标签: c++ casting override covariant

这是我的问题所在的课程

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. 我可以覆盖不同返回类型的函数吗? Node * getNode(int index)成为TransformationNode * getNode(int index)

      
        

    是的,只要返回类型是协变的:http://www.tolchz.net/?p=33

      
  2. 我可以覆盖会员吗?

      
        

    我不知道覆盖,但派生类中具有相同名称的变量将隐藏基类中的变量

      
  3. 还有一个问题我真的很想解决一些问题

    在TransformationNode类中,我做了很多(恕我直言)可避免的类型转换,从基类到派生类。我肯定知道mNodeList向量中的所有元素都是TransformationNodes但是为了处理mNodeList,我必须输入它们。

    继承是正确的我的意思是TransformationNode是一个节点

    mNodeList保存节点的子节点,并且在派生类中没有副本,该类具有类型的节点版本

    如果static_cast成本更高,我甚至可以使用reinterpered_cast。你能告诉我这些操作的费用吗?他们真的是性能问题吗?
    断言(dynamic_cast)......已经采取了一些预防措施。



    简单地说我希望我的编译器知道mGraph实际上是一个SceneGraph *并且mNodeList包含TransformationNode *这有助于我避免丢失类型转换。


    感谢您抽出宝贵时间

1 个答案:

答案 0 :(得分:1)

1)是正确的,如果返回类型更多,你确实可以覆盖(virtual!)基函数。

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

将整个接口放入基类,但只在每个具体类中实现。