以下是我的问题是关于的类
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类中,我进行了许多(IMHO)可避免的类型转换,从基类转换为派生类。我肯定知道mNodeList向量中的所有元素都是TransformationNodes,但要处理mNodeList,我必须对它们进行类型转换
继承是正确的我的意思是TransformationNode是一个节点
mNodeList包含节点的子节点,并且在派生类中不能有副本,该派生类包含nodes的类型转换版本
最后,如果static_cast成本更高,我甚至可以使用reinterpered_cast。你能告诉我这些手术的费用吗?它们真的是性能上的大问题吗?
assert(dynamic_cast)。。。已经采取了某种预防措施。
简单地说,我想让我的编译器知道mGraph实际上是一个SceneGraph*,mNodeList包含TransformationNode*,这有助于我避免类型转换丢失
感谢您慢慢来
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;
};
将整个接口放入基类中,但仅在每个具体类中实现。