Section 1 - Polymorphism

6A.1.1 Orientation

scenic damAn important aspect of inheritance is the use of what we call virtual member functions, also known as virtual methods or virtual functions.  The more you get into C++ programming, the more you will use pointers to objects, rather than objects themselves.  We want pointers to be able to point to either base class or derived class objects, and indeed, as you learned in CS 2A, base class pointers can point to either.  However, pointing to an object and getting access to the objects methods are not the same thing, as we shall see.

Stated another way, that relates to you directly, a problem that you didn't even knew existed, is about to become the main topic in your life for the next couple hours.

Finally, we put this to work on a real-world application, barcode scanning software.

6A.1.2 Reading and Resources

All the resources needed for this week and instructions on textbook reading have already been posted in module sections A1 of the first three weeks. Refer to those pages and links, regularly.

6A.1.3 The Need for a Polymorphism

Last week I gave you an example of inheritance that used a base class StackNode and a derived class FloatNode.  I also provided a second pair of classes Stack and FloatStack that our main() would use to push and pop.  There was one method in the Stack class that I defined but never used: showStack().  That method plows through the list of StackNodes and displays each one, individually.  It is a bit of a diagnostic tool, because normally we don't look inside Stacks to see what they contain, but rather merely push and pop items to/from it.  Nevertheless, showing the data on a stack (without removing anything from the stack) is a common practice.  Let's test out our showStack() method in a short main().

// main method ---------------------------------------
int main()
{
  FloatStack fstk;

  fstk.push(1.1);
  fstk.push(2.2);
  fstk.push(3.3);
  fstk.push(4.4);

  fstk.showStack();

  cout << endl;
  return 0;
}

We run it and receive the following bad news:

console shot

What happened?  Look at the definition of showStack().  It appears in the base class Stack.  Here it is:

void Stack::showStack()
{
  StackNode *p;

  // Display all the nodes in the stack
  for( p = top; p != NULL; p = p->next )
    p->show();
  }

The problem appears to be that we are moving through the Stack using a StackNode pointer, p.  Sure, the stack happens, in our current program, to be a stack of FloatNodes (derived from StackNodes), but showStack() doesn't know that, and certainly our hired minimum wage laborer, p, can't know it either.  The pointer p, was declared to be a StackNode * so it assumes its goal in life is to point to generic StackNodes.  Therefore, it interprets the method show() to be the method defined in the base class.

It would be great if we could use a base class pointer for everything and have it somehow just "know" whether it was pointing to a base class object or a derived class object.  Even better,  if there were several classes derived from one base class, it would be especially good for that pointer to know which class the object to which it points, belongs.

This desirable behavior is called polymorphism and in C++ virtual functions provide it.

creater late from space