Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 处理不同节点类型的树_C++_Tree - Fatal编程技术网

C++ 处理不同节点类型的树

C++ 处理不同节点类型的树,c++,tree,C++,Tree,我有一个树数据结构,它可以有从一个TreeBaseNode类派生的不同类型的节点。我制作了TreeBaseNode*类型的树节点,它在运行时被分配给不同特殊节点的对象。 当遍历树上的树时,如何从TreeBaseNode*指针访问aNodeAttribute(如果节点类型为SpecialNodeA,我可以从NodeType中识别该节点) 编辑:更改类型 C++中的数据成员没有多态性,但可以使用函数成员的多态性。因此,您应该在基类中声明virtual int getNodeAttribute(){}

我有一个树数据结构,它可以有从一个
TreeBaseNode
类派生的不同类型的节点。我制作了
TreeBaseNode*
类型的树节点,它在运行时被分配给不同特殊节点的对象。 当遍历树上的树时,如何从
TreeBaseNode*
指针访问
aNodeAttribute
(如果节点类型为
SpecialNodeA
,我可以从
NodeType
中识别该节点)


<>编辑:更改类型

C++中的数据成员没有多态性,但可以使用函数成员的多态性。因此,您应该在基类中声明
virtual int getNodeAttribute(){}
。然后在两个派生类中重新实现它,以返回您想要的属性。

米伦建议的替代方法是使用
动态\u cast
将您知道的属于
特殊节点类型的节点从
树节点
向下转换为
特殊节点
,然后只需调用适当的成员即可函数来检索要查找的属性


在这个特定的场景中,您甚至可以取消基类中的
NodeType
成员,因为非此类型的节点上的
dynamic\u cast
将简单地返回空指针。我不太喜欢基类必须了解其派生类型的层次结构,因为这样做会消除类层次结构的一些好处,并且倾向于认为设计没有它应该的那么干净

基于评论中的额外信息,为什么不添加一个公共
虚拟整数估计()=0
到基类(假设估计的结果是
int
),并在派生类中重写它?i、 e.将估算专业与专业类别联系起来。这样,您就不必处理多态代码来提取特定于类型的字段。

如果您通过指向基类的指针访问所有内容,这意味着您不关心特定对象的类型。但从你的问题来看,听起来你真的很在乎。这听起来你需要重新思考你的设计…我知道设计很糟糕。我怎样才能修改它。我可以只使用一种节点类型和所有属性,但其中一些不会被使用(取决于节点类型)。这同样是一个糟糕的设计,对吧?@iNoam:如果不知道您打算如何使用数据结构,很难说…@Oli根据
节点类型
我想使用属性来估计一些东西。它在类外完成,同时遍历节点。例如,如果它是一个
SpecialNodeA
,我将调用一个函数,其中
commonNodeAttributeA
CommonNodeAttribute
aNodeAttribute
作为参数。@iNoam:Ok。但是如果
aNodeAttribute
bNodeAttribute
是可互换的(即如果@Mihran的答案可以解决您的问题),那么您也可以用基类中的单个属性替换它们。答案很好!我完全忘了选角。这个答案是正确的。但是一个依赖于
dynamic\u cast
的设计也是不干净的!好的,我明白了。但如果我这样做,那会是一个有缺陷的设计吗。或者您希望只有一个节点类(根据节点类型,某些属性一次处于活动状态)?这是正确的,假设OP不关心他是否获得
aNodeAttribute
bNodeAttribute
。不,这是一个不错的设计。但我有个问题要问你@iNoam。如果在两个派生类中,属性都是整数,为什么不将其作为基类的一部分呢?如果可能存在其他类型的属性,那么为什么不使用boost::any或boost::variant呢?实际上,这是对我的问题的过度简化表示。在实际场景中,它们都是不同类型的。那么你的问题就不清楚了。因为这种情况下虚拟函数对你没有帮助。而且您不能声明虚拟函数的模板。所以,认为boost::variant和boost::any是将基类作为可能的属性放入的更好方法,一点也不用担心。
class TreeBaseNode
{
public:
    int NodeType;   
    TypeA commonNodeAttributeA,
    TypeB commonNodeAttributeB; 
};

class SpecialNodeA : public TreeBaseNode
{
private:

    TypeD aNodeAttribute

public:
    SpecialNodeA(int type)
    {
        NodeType = type;
    }
    //Methods   
};

class SpecialNodeB : public TreeBaseNode
{

private:

    TypeE bNodeAttribute;

public:
    //Methods


};