Section 1 - Deriving a FloatNode

4B.1.1 Building From a Base Class

scenic road sign

Let's say we wish to create a real, useful stack of floats from our generic stack of "nothings."  The first step will be to create a new node called FloatNodeFloatNode will be derived from StackNode and therefore will not have to duplicate any data or linking methods.  It only has to add the float data to it.  That's what deriving classes is all about.

This process is beautifully simple.  Here is the FloatNode prototype:

class FloatNode : public StackNode
{
private:
    float data;
public:
    FloatNode(float x);
    void show();
    float getData();
};

As you see, it is derived from StackNode.  It has only one member, the float data.  It has one constructor, and it overrides the show() method of the base class.  I'll bet you could even write the methods for this class without looking, but I'll give them to you, anyway:

// FloatNode method definitions --------------------------
FloatNode::FloatNode(float x)
{
    data = x;
}

void FloatNode::show()
{
   cout.setf(ios::fixed);
   cout.precision(3);
   cout << "[" << data << "] ";
}

float FloatNode::getData()
{
return data;  // simple accessor
}
// end FloatNode method definitions ---------------------

I added some fancy number formatting just to make sure the floats are printed out neatly, and that could be omitted, to make the class even simpler.  Notice how you have to know absolutely NOTHING about the base class nodes.  You only add the float data and methods that manipulate that.

4B.1.2 Working From a Base Class

We will stop a moment to try out our new FloatNodes.  This is not something you would ever do in your client, but it helps to see how FloatNodes can be manipulated.

int main()
{
    FloatNode flt1 = 3.33, flt2 = 4.44, flt3 = 5.55, *p;

    // link up our three FloatNodes
    flt1.next = &flt2;
    flt2.next = &flt3;

    // show the stack
    for ( p = &flt1; p != NULL; p = (FloatNode*)(p->next) )
    {
    p->show();
    }
    cout << endl;
    return 0;
}

This is very simple.  There is one phrase that confuses us, but we can explain that:

p = (FloatNode*)(p->next)

We would like this phrase to be

p = p->next

After all, this is the iteration step in our for loop, and we already saw that this is how a node pointer, p, takes a step to the next node.  The problem is that p->next is a StackNode * type and p is a FloatNode * type.  Remember the golden rule of assignments between base and subclass types?  Therefore, we do a type cast (coercion) to force the type to be compatible.  This is safe since all pointers are the same size.

Besides that, the linking up of the data is the same as if they were ordinary StackNodes.

Here is the run:

console shot

But we want to do better than this.  We want a FloatStack, and we want the main() to look much cleaner.  Once you understand the above, you can turn the page to see the next, exciting step.