Then, using a pointer to the base class, the program can point
at a variety of objects of the derived classes and when the overridden
function is called, it is the one for the type of the object
being pointed at. Without virtual functions, the function called is the
one for the type of the pointer.
The code for this is available in the examples folder.
#include <stdio.h>
#include <stream.h>
#include <stdlib.h>
#include <string.h>
class instrument {
public:
void play(int
note) { cout << "instrument::play" << endl;}
}; // instrument
class wind : public instrument {
public:
void play(int
note) { cout << "wind::play" << endl;}
}; // wind
void tune(instrument& i)
{
i.play(1);
}
main()
{
wind flute;
tune(flute);
} // main
This prints instrument::play. This is because the variable in tune() is of type instrument so it uses the function from there, even though we passed in a flute. Change the definition in instrument to:
virtual void play(int note) { cout << "instrument::play" << endl;}
Now running the program prints wind::play. The function to be called is determined at run time (late binding). This technique allows us to write functions like tune() that will work for any derived class from a base class. It is easier to extend the classes because tune() still works for other classes derived from instrument. Like drum or guitar. It will also work for lower levels. If class brass is derived from wind, tune() still works. If there is no overridden functions, the one next up the hierarchy is used.
Here is a somewhat larger, less abstract example. The code for this is available in the examples folder.