Section 2 - Virtual Functions
6A.2.1 Virtual Functions Defined
We know that a base class pointer can point to a derived class object without a type cast. This is a fundamental rule of inheritance that we learned earlier in this course. However, even if a base class pointer is pointing to a derived class object, it cannot be used to access the data or methods that are unique to the derived class. It can only access the base class portion of the object.
Furthermore, if the base class and derived class have functions with the same name, a base class pointer pointing to a derived object will not be able to get at the derived version of the function. We saw that with our StackNodes and FloatNodes above and we can see it even more clearly in this small, self-contained example:
#include <iostream> using namespace std; // --------- BASE AND DERIVED CLASSES ------------- class Base { public: void fun() { cout << "Base\n"; } }; class Derived : public Base { public: void fun(){ cout << "Derived\n"; } }; // ---------------- CLIENT ------------------------- void main() { Base b, *bp = &b; Derived d, *dp = &d; bp->fun(); dp->fun(); bp = dp; bp->fun(); }
This is the output produced:
Base Derived Base
The third function call, bp->fun(), invoked the base class fun() even though the pointer bp was pointing to a derived class object. Evidently, the function called depends on the pointer, not the object to which it points.
However, with virtual functions, the function called depends on the object pointed to, not the pointer. To use virtual functions we make one trivial adjustment to our code. We add the keyword virtual to the front of the base class method definition.
class Base
{
public:
virtual void fun() { cout << "Base\n"; }
};
class Derived : public Base
{
public:
void fun(){ cout << "Derived\n"; }
};
Now we get a different result:
Base Derived Derived
We can now distinguish objects, even if we are pointing to them with a base class pointer. The base class can have a virtual function, show(), and there can be seven varieties of derived classes that have show() as a Base:
class Variety1 : public Base { public: void show(); // ... class Variety2 : public Base { public: void show(); // ...
and so on. The show() function may be different for each derived class. If a base class pointer, bp, is used to variously point to different derived objects, the call
bp->show();
will result in differing output.
This is true polymorphism. As simple as it seems, it enables C++ to be used in a powerful way.
6A.2.2 Problem Solved
How do we apply this to our StackNode/FloatNode example? We add the virtual to the front of the base class's show() method (in the prototype only). Everything else is the same.
// Class StackNode ----------------------------------
class StackNode
{
public:
StackNode *next;
StackNode();
~StackNode();
virtual void show();
};
After you make that change, rerun the client at the top of this section. You get the following good news:

Excellent! Go back and look at the definition of showStack() and see that, without even knowing what kind of bizarre StackNodes our descendents might someday derive, this pointer p now has the intelligence to call the derived version of the show() method.