## Highlights of this lab:

In this lab,  you will:

Note: To see the version of this lab WITHOUT pointers in the code, refer to this link.

## Lab Exercise:

• The purpose of the program is to illustrate the concept of polymorphism by creating derived classes that define their own operations in virtual functions.
• A base class contains a pure virtual function but the actual function definitions are contained in the individual derived class functions.

Click the little computer above for a detailed description.

NOTE: You do NOT have to hand in this lab exercise, but doing it will help you in your class work. There will be questions on the class quizzes and exams based on the lab material.

If you need help during the week, you are welcome to go to CL119 during Office Hours posted for lab instructors.

## Virtual Functions and Polymorphism.

Before getting into the details of virtual functions, let's have a look at why you need such things at all!!

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 push and pop operators are akin to setting temperatures on a thermostat.
• The stack is akin to a furnace. Just as you can have any type of furnace, you can have any kind of stack - integer, float, character, and so on.

The idea behind all this is to simplify the life of the operator - the programmer.

## Declaring a Virtual Function in C++.

A virtual function is declared in a base class of a program and can then be redefined in each derived class. The declaration in the base class acts as a kind of template which can be enhanced by each derived class.

• In the base class, you must begin the function declaration with the keyword virtual.

• The keyword virtual is not used in the derived functions.

• The number and type of parameters in the derived function must match the number and type in the initial declaration of the virtual function.

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_ptr;	// declare a pointer for the base class
base_class base;	// declare an object of the base class

base_ptr = &base;	// point to the new object
base_ptr->printit();	// execute its virtual function

first_class first1;	// declare an object of the derived class

base_ptr = &first1;	// point to the new object
base_ptr->printit();	// execute its virtual function

} // end main function

```
This is what you would see if you ran that program:
```	Print from base class

Print from first class
```

A few notes about virtual functions:

• The keyword virtual is used only in the base class declaration.

• When a derived class redefines the virtual function in a base or predecessor class, this is referred to as overriding the function. Don't confuse this with overloading a function.

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.)

• Friend functions cannot be virtual, nor can constructor functions, although destructor functions can be virtual.

## Virtual Functions and Inheritance

• A derived class does not have to redefine (override) a virtual function. You'll see in the following example, that the "second_class" class relies on the definition of the virtual function in the base class. In other words, if a derived class does not specify code for the virtual function, then the code in the predecessor function is used.

• A derived function inherits the virtual functions of its predecessors which may or may not be the base class. Notice in the following example how the "tourist_class" is derived from the "coach_class". "tourist_class" does not override the virtual function, so the definition in the immediate predecessor, in this case "coach_class", is used.
```/* Filename: pub/class/170/ftp/cpp/Vfuncs/ex2-wptrs.cpp   */

#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_ptr;   // declare a pointer for the base class
base_class base;        // declare an object of the base class

base_ptr = &base;         // point to the new object
base_ptr->printit();    // execute its virtual function

first_class first1;     // declare an object of the derived class

base_ptr = &first1;       // point to the new object
base_ptr->printit();    // execute its virtual function

second_class second1;     // declare an object for second
base_ptr = &second1;
base_ptr->printit();

coach_class coach1;     // declare an object for coach
base_ptr = &coach1;
base_ptr->printit();

tourist_class tour1;     // declare an object for tourist
base_ptr = &tour1;
base_ptr->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 PrintedSource 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 Mercury's ftp site. 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 Mercury's anonymous ftp site.

```The path:	pub/class/170/ftp/cpp/Vfuncs

The file:      ex2-wptrs.cpp
```

## Pure Virtual Functions

As you've seen in the previous example, if a derived class does not override a virtual function, it is the function definition in a predecessor class that is used. If the immediate predecessor has not overriden its predecessor, then the one before that is referenced to find a function definition. This search could continue (if predecessors don't override the virtual function) until, ultimately, it is the function definition in the base class that is used.

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.

## Lab Exercise -- C++ Virtual Functions

As stated in the first lab, there is nothing to hand in for lab exercises. There will be question on lab material in class tests. Also, you will learn the lessons presented in the lab material more easily when you perform the lab exercise.

• Use the Hercules command-line ftp program to copy this file from Mercury's anonymous ftp site.
```The path:	pub/class/170/ftp/cpp/Vfuncs

The file:      vfuncs-wptrs.cpp
```
• The purpose of the program is to illustrate the concept of polymorphism by creating derived classes that define their own operations in virtual functions.
• A base class contains a pure virtual function but the actual function definitions are contained in the individual derived class functions.

• Compile and run this C++ program.

• Modify the code as indicated by the comments in the program.

• Compile and run this program again.