2
votes

I am having a tree data structure that can have different types of nodes deriving from one TreeBaseNode class. I have made the tree nodes of type TreeBaseNode * which gets assigned to objects of different Special nodes at run time. How can I access aNodeAttribute from the TreeBaseNode* pointer while traversing the tree on the tree is generated (if the node is of type SpecialNodeA which I can identify from NodeType)

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


};

EDIT: changed the types

3
If you're accessing everything through pointers-to-base-class, it implies that you don't care what type a particular object is. But from your question, it sounds like you do care. This sounds like you need to re-think your design... - Oliver Charlesworth
I understand that the design is bad. How could I modify it. I could have just one node type with all the attributes, but some of it would not be used (depending on the NodeType). That again would be bad design, right? - softwarematter
@iNoam: Without some idea of how you intend to use your data structure, it's hard to say... - Oliver Charlesworth
@Oli Depending on the NodeType I want to use the attributes to estimate something. It is done outside the class while traversing through the nodes. For instance if it is a SpecialNodeA, I would call a function with commonNodeAttributeA, commonNodeAttributeB and aNodeAttribute as parameters. - softwarematter
@iNoam: Ok. But if aNodeAttribute and bNodeAttribute are interchangeable (i.e. if @Mihran's answer will solve your problem), then you may as well replace them with a single attribute in the base class. - Oliver Charlesworth

3 Answers

4
votes

There is no polymorphism of data-members of clases in c++, but you can use polymorphism of function-members. So you should declare virtual int getNodeAttribute(){} in your base class. And reimplement it in two Derived classes to return attribute what you want.

2
votes

An alternative to Mihran's suggestion would be to use dynamic_cast<> to cast those nodes that you know are of type SpecialNodeA from TreeBaseNode down into a SpecialNodeA and then just call an appropriate member function to retrieve the attribute you're after.

In this particular scenario you can even do away with the NodeType member in the base class as a dynamic_cast<SpecialNodeA> on a node that isn't of this type will simply return a null pointer. I'm not too fond of hierarchies where the base class has to have knowledge of its derived types as that does away with some of the benefits of a class hierarchy and tends to suggest the design isn't as clean as it should be.

0
votes

Based on the extra information in the comments, why not add a public virtual int estimate() = 0; to the base class (assuming that the result of the estimation is an int), and override it in the derived classes? i.e. tie the estimation specialisations to the specialised classes. That way, you don't have to deal with polymorphic code to extract the type-specific fields.