In this lab, you will:
In C++ The Complete Reference, Schildt says that a class that contains a virtual function is called a polymorphic class. This begs the question "What is polymorphism?". Schildt gives a very nice example of this term. He says to consider a house with an ordinary thermostat to control temperature. You know the house has a furnace but you don't know what kind. If you want to set the temperature you simply set the thermostat to the desired temperature. You don't know (or likely really care at all) how the furnace accomplishes its task. It might be a gas furnace, an electric heater, solar power - you don't care. You leave it up to the furnace to do its own task in a manner appropriate to that device.
How does this relate to polymorphism? Well, an analogy to computer programming is the concept of push/pop operations on various kinds of stacks.
The idea behind all this is to simplify the life of the operator - the programmer.
Here is a simple example.
#include <iostream> using namespace std; /*------------------------------------------------- Class Name: base_class -------------------------------------------------*/ class base_class { // The keyword VIRTUAL must be used here!! public: virtual void printit() { cout << "Print from base class\n"; } }; // end base_class /*------------------------------------------------- Class Name: first_class -------------------------------------------------*/ class first_class : public base_class { public: void printit() { cout << "Print from first class\n"; } }; // end first_class /************************************************** Name: main **************************************************/ void main() { base_class base; // declare an object of the base class base.printit(); // execute its virtual function first_class first1; // declare an object of the derived class first1.printit(); // execute its virtual function } // end main functionThis is what you would see if you ran that program:
Print from base class Print from first class
A few notes about virtual functions:
When you call an overriding function, you must supply the same number and type of parameters as the original. (You'll remember that the opposite is true for an overloaded function call.)
#include <iostream> using namespace std; /*------------------------------------------------- Class Name: base_class -------------------------------------------------*/ class base_class { // The keyword VIRTUAL must be used here!! public: virtual void printit() { cout << endl << "Print from base class" << endl; } }; // end base_class /*------------------------------------------------- Class Name: first_class -------------------------------------------------*/ class first_class : public base_class { public: void printit() { cout << endl << "Print from first class" << endl; } }; // end first_class /*------------------------------------------------- Class Name: second_class -------------------------------------------------*/ class second_class : public base_class { }; // end second_class /*------------------------------------------------- Class Name: coach_class -------------------------------------------------*/ class coach_class : public base_class { public: void printit() { cout << endl << "Print from coach class" << endl; } }; // end coach_class /*------------------------------------------------- Class Name: tourist_class -------------------------------------------------*/ class tourist_class : public coach_class { }; // end tourist_class /************************************************** Name: main **************************************************/ void main() { base_class base; // declare an object of the base class base.printit(); // execute its virtual function first_class first1; // declare an object of the derived class first1.printit(); // execute its virtual function second_class second1; // declare an object for second second1.printit(); coach_class coach1; // declare an object for coach coach1.printit(); tourist_class tour1; // declare an object for tourist tour1.printit(); } // end main function
Here is what happens when that program is run:
mercury[20]% ex2 Print from base class Print from first class Print from base class Print from coach class Print from coach class mercury[21]%Examine the program and the output carefully to understand how it works.
Line Printed | Source of printing |
---|---|
Print from base class | This is the base class virtual function. |
Print from first class | This is the first class virtual function. |
Print from base class | This is the second class virtual function.
But since there is no virtual function defined in "second class", the definition in the predecessor function is used. i.e. The base function. |
Print from coach class | This is the coach class virtual function. |
Print from coach class | This is the tourist class virtual function.
But since there is no virtual function defined in "tourist class", the definition in the predecessor function is used. In this case, the predecessor class is not "base" class, but "coach" class. |
If you would like to experiment with that program you can copy it from the CS FTP Server. There are some comments in the program suggesting how you might modify the classes. To copy the program use the Hercules command-line ftp program from the CS FTP Server.
The path: pub/class/170/ftp/cpp/Vfuncs The file: ex2-noptrs.cpp
However, in some cases, it does not make sense for the base class to define the virtual function at all. The actual method should really be implemented in each one of the descendent classes. The base function should simply provide a kind of placeholder for the virtual function and leave it up to the descendents to specify the individual methods.
A virtual function that is declared but not defined in a base class is referred to as a pure virtual function. Here is the general syntax for declaring a pure virtual function:
virtual type function_name(parameter_list)=0;Now when the base class uses a PURE virtual function, each descendent must override that function, or you will get a compile error. This makes sense, because the function has to be defined somewhere.
Here's another definition for you:
If a class contains a pure virtual function, that class is
called an
abstract class.
Because there is no definition for the function,
you cannot create an object of that class.
You can however, declare pointers to it.
Think of an abstract class as a general class that lays the foundation for descendent classes that define their own methods. This is the heart of polymorphism - let each class define its own operation.
The lab exercise in the next section illustrates these concepts. Study the C++ program for the exercise carefully, and be sure to read the comments.
|
|
|