Virtual Functions in C++ Part I

Virtual functions in C++ play an important role. To understand virtual function, one should be clear about the polymorphism feature of C++ language as an object oriented language. In brevity, polymorphism is the weapon through which we can identify a function call through its parameters, or different types of parameters or maybe in base and derived class relationship. However, the behavior of function call decided at the compile time is called static polymorphism and the one decided at the runtime is called dynamic polymorphism. Virtual functions come into picture in case of dynamic polymorphism, which includes usage of pointers involving the derived and base class objects to decide which function behavior would be called.

Introduction

The virtual functions are defined in a base class, where same signature function is being defined in the derived class, making the base class function also getting publically inherited by the derived classes. So now, which function needs to be called i.e. one which is defined in the base class, or the one that is defined in the derived? This dynamic binding happens at runtime, and is leveraged using virtual functions.
A virtual function prototype looks as:

Code:

virtual int printData();

We shall be going in more details, when to use and how it works in further sections.

Using Virtual functions

Let us understand a scenario where we would need to use virtual functions. We would be designing and coding classes for a basic integer arithmetic calculations. As a simple design paradigm, we'll be having a base class with a bare minimum integer operand and an abstract calculate method. Each specific arithmetic operation can be handled as a separate class.

The baseArithmetic class has a bare minimum one operand, and a compute() method which returns the operand, as the base class does not implement any specific arithmetic operation. Moving on to the specific arithmetic operation classes, which gets inherited from the above base class. Following are the class definitions of Add, Subtract, Multiply and Divide.

ubuntu@ubuntu-VirtualBox:~$ g++ main.cpp -o main
ubuntu@ubuntu-VirtualBox:~$ ./main
Enter number corresponding to what operation you want to do: -
1. Add
2. Subtract
3. Multiply
4. Divide
1
Enter the operators, first and second
3
6
The result is 3
$./main

Oh! It is incorrect. Addition of 3 and 6 cannot be 3. If we observe the result we obtained, it is actually the base class function which got called. The reason was, the pointer 'ba' is a pointer of type 'baseArithmetic'. Hence, when the 'compute()' method is called using this pointer, base method is called.

How to do make it work as we desire? It is using the virtual function. Here, we would have to declare 'compute()' function of the base class as virtual, so that if the derived class has same signature function, derived one will be called if the pointer contains object of the derived class.

This is how now our base class 'baseArithmetic' looks, including the virtual function.

Making just this minor change to modify the base class function to a virtual function will rectify our program.

Compiling and running again,

Code:

ubuntu@ubuntu-VirtualBox:~$ g++ main.cpp -o main
ubuntu@ubuntu-VirtualBox:~$ ./main
Enter number corresponding to what operation you want to do: -
1. Add
2. Subtract
3. Multiply
4. Divide
1
Enter the operators, first and second
3
6
The result is 9

It runs as expected now.

The Function Signature

In the case of overriding or virtual functions, there is an implicit requirement of the function signature should be the same. The function signature includes the name of the function and the return type.
In the following prototype,

Code:

int function(int a, int b);

For the above function prototype, function signature is considered as

Code:

int func

Hence, a virtual function is a legitimate virtual function if the derived class holds a method with the same name and same return type i.e. the same function signature.
To look to an example,