3

这是我的问题所涉及的课程

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. 我可以覆盖成员吗?

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

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

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

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

mNodeList 包含节点的子节点,并且它不能在包含节点的类型转换版本的派生类中具有副本

最后,如果 static_cast 成本更高,我什至可以使用 reinterpered_cast。你能告诉我这些手术的费用吗?它们真的是很大的性能问题吗?
assert (dynamic_cast)... 已经采取了某种预防措施。



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


感谢您抽出宝贵时间

4

1 回答 1

1

1) 是正确的,如果返回类型更加派生,您确实可以覆盖(虚拟!)基本函数。

广告 2):确实,您不能“覆盖”成员。如果您需要更灵活的可覆盖行为,请重新设计基类。

static_cast是在编译时解决的静态操作,就像reinterpret_cast它没有任何“成本”一样。


正如@Seth 在评论中所建议的那样,移动容器可能是一种选择。问问自己,是否有一个 abstract 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;
};

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

于 2012-01-14T23:53:03.263 回答