这是我的问题所在的课程
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;
}
首先,我想谈谈我解决的问题。他们可以帮助他人。如果我是对的,你可以确认我^^
我可以覆盖不同返回类型的函数吗? Node * getNode(int index)成为TransformationNode * getNode(int index)
是的,只要返回类型是协变的:http://www.tolchz.net/?p=33
我可以覆盖会员吗?
我不知道覆盖,但派生类中具有相同名称的变量将隐藏基类中的变量
还有一个问题我真的很想解决一些问题
在TransformationNode类中,我做了很多(恕我直言)可避免的类型转换,从基类到派生类。我肯定知道mNodeList向量中的所有元素都是TransformationNodes但是为了处理mNodeList,我必须输入它们。
继承是正确的我的意思是TransformationNode是一个节点
mNodeList保存节点的子节点,并且在派生类中没有副本,该类具有类型的节点版本
如果static_cast成本更高,我甚至可以使用reinterpered_cast。你能告诉我这些操作的费用吗?他们真的是性能问题吗?
断言(dynamic_cast)......已经采取了一些预防措施。
简单地说我希望我的编译器知道mGraph实际上是一个SceneGraph *并且mNodeList包含TransformationNode *这有助于我避免丢失类型转换。
感谢您抽出宝贵时间
答案 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;
};
将整个接口放入基类,但只在每个具体类中实现。