C ++处理派生的类别的自我参考
-
29-09-2019 - |
题
所以假设我在C ++中有这样的树类
class Node{
void addChild(Node*);
/*obvious stuff*/
protected:
Node* parent;
vector<Node*> children
}
class specialNode : public Node{
void addChild(specialNode*);
/*obvious stuff*/
/*special stuff*/
}
现在,每当我在特殊树木中访问孩子时,我显然会得到节点*,而不是SpecialNode*。
但是,此特殊Node*具有Node没有的成员变量和函数。
我可以强迫SpecialNode只能将Special Node作为孩子,而在编译时间中会中断,但是在访问孩子/父母时,我仍然会得到Node*,即使我想使用特殊功能,即使在Special Nonode功能中,我也必须施放它。
有什么聪明的,还是有什么更好的方法?除了每次铸造吗?
解决方案
如果您只需要 SpecialNode
树上的对象(只想将所有通用树功能封装在 Node
) 你(们)能做到 Node
一个所谓的“混合”课
template <class N>
class Node : public N {
public:
void addChild(Node<N>*);
protected:
Node<N>* parent;
vector<Node<N>*> children;
};
class SpecialNodeBase {
// Here comes all "special" data/methods for your "special" tree
};
typedef Node<SpecialNodeBase> SpecialNode;
之后,您可以构造一棵树 SpecialNode
对象并使用所有方法 SpecialNodeBase
以及来自 Node
其他提示
因为您的子类中的addChild功能不是多态性的,所以将其虚拟化,但是不允许在基础/儿童成员之间实现过载功能,因此我们必须更改子类中的AddChild参数:
class Node{
virtual void addChild(Node*);
...
}
class specialNode : public Node{
virtual void addChild(Node*);
...
}
现在,它应该起作用。
如果您想访问 childeren
儿童课的变量(specialNode
上课),您应该施放它。例如:
specialNode* var = static_cast<specialNode*>(children[i]);
由于我们将AddChild声明为虚拟函数,因此我们应该使用 dynamic_cast
代替 static_cast
如果我们不确定 children[i]
总是一个实例 specialNode
班级,因此最好使用 dynamic_cast
:
specialNode* var = dynamic_cast<specialNode*>(children[i]);
if(var != NULL)
{
//...
}
如果我正确理解,“混合”类解决方案将不允许您致电 addChild
从实施的功能 SpecialNodeBaseClass
.
您实际上可以执行以下操作:
template <class recursiveT>
class Base {
public:
Base(dataType data) { populate children with data; }
void addChild() { something base class appropriate; }
protected:
std::vector<recursiveT> children;
};
class Derived: public Base<Derived> {
public:
/* note: the constructor here will actually call the
constuctor of the base class */
Derived(dataType data) : Base<Derived>(data) {}
/* other special functions go here. */
};
这看起来可能有点疯狂,但是它在几个GCC版本上对我来说很干净,所以我倾向于认为这不是完全错误的。现在,您应该能够从内部派生中调用碱的功能。
您一定必须施放 Node *
到 specialNode *
在某个时候,您只能在一个地方进行此操作,可以使这种干净易于管理。您可以添加成员功能,说 getParent
并覆盖它 specialNode
, , 像这样:
class Node {
...
virtual Node *getParent() {
return parent;
}
};
class specialNode : public Node {
...
specialNode *getParent() {
return dynamic_cast<specialNode *>(parent);
}
};
当然,这是假设 specialNode
S总是有其他 specialNode
作为父母/孩子。如果您混合 Node
沙 specialNode
S,这显然无法正常工作。