Virtual Functions and Runtime Polymorphism in C++

22 Jun, 2022
A virtual function is a member function that is declared in the base class using the keyword virtual and is re-defined (Overriden) in the derived class. It tells the compiler to perform late binding where the compiler matches the object with the right called function and executes it during the runtime. This technique of falls under Runtime Polymorphism.
The term Polymorphism means the ability to take many forms. It occurs if there is a hierarchy of classes that are all related to each other by inheritance. In simple words, when we break down Polymorphism into ‘Poly – Many’ and ‘morphism – Forms’ it means showing different characteristics in different situations. 
Class Hierarchy
Note: In C++ what calling a virtual functions means is that; if we call a member function then it could cause a different function to be executed instead depending on what type of object invoked it. Because overriding from derived classes hasn’t happened yet, the virtual call mechanism is disallowed in constructors. Also to mention that objects are built from the ground up or follows a bottom to top approach.
Consider the following simple program as an example of runtime polymorphism. The main thing to note about the program is that the derived class’s function is called using a base class pointer.The idea is that virtual functions are called according to the type of the object instance pointed to or referenced, not according to the type of the pointer or reference.In other words, virtual functions are resolved late, at runtime.
Now, we’ll look at an example without using the concepts of virtual function to clarify your understanding.
C++
// C++ program to demonstrate how we will calculate// area of shapes without virtual function#include <iostream>using namespace std; // Base classclass Shape {public:    // parameterized constructor    Shape(int l, int w)    {        length = l;        width = w;    }    int get_Area()    {        cout << "This is call to parent class area\n";        // Returning 1 in user-defined function means true        return 1;    } protected:    int length, width;}; // Derived classclass Square : public Shape {public:    Square(int l = 0, int w = 0)        : Shape(l, w)    {    } // declaring and initializing derived class    // constructor    int get_Area()    {        cout << "Square area: " << length * width << '\n';        return (length * width);    }};// Derived classclass Rectangle : public Shape {public:    Rectangle(int l = 0, int w = 0)        : Shape(l, w)    {    } // declaring and initializing derived class    // constructor    int get_Area()    {        cout << "Rectangle area: " << length * width             << '\n';        return (length * width);    }}; int main(){    Shape* s;     // Making object of child class Square    Square sq(5, 5);     // Making object of child class Rectangle    Rectangle rec(4, 5);    s = &sq; // reference variable    s->get_Area();    s = &rec; // reference variable    s->get_Area();     return 0; // too tell the program executed    // successfully}
This is call to parent class area
This is call to parent class area
In the above example:
We store the address of each child’s class Rectangle and Square object in s and
Then we call the get_Area() function on it,
Ideally, it should have called the respective get_Area() functions of the child classes but
Instead, it calls the get_Area() defined in the base class.
This happens due to static linkage which means the call to get_Area() is getting set only once by the compiler which is in the base class.
Example: C++ Program to Calculate the Area of Shapes using Virtual Function
C++
// C++ program to demonstrate how we will calculate// the area of shapes USING VIRTUAL FUNCTION#include <fstream>#include <iostream>using namespace std; // Declaration of Base classclass Shape {public:    // Usage of virtual constructor    virtual void calculate()    {        cout << "Area of your Shape ";    }    // usage of virtual Destuctor to avoid memory leak    virtual ~Shape()    {        cout << "Shape Destuctor Call\n";    }}; // Declaration of Derived classclass Rectangle : public Shape {public:    int width, height, area;     void calculate()    {        cout << "Enter Width of Rectangle: ";        cin >> width;         cout << "Enter Height of Rectangle: ";        cin >> height;         area = height * width;        cout << "Area of Rectangle: " << area << "\n";    }     // Virtual Destuctor for every Derived class    virtual ~Rectangle()    {        cout << "Rectangle Destuctor Call\n";    }}; // Declaration of 2nd derived classclass Square : public Shape {public:    int side, area;     void calculate()    {        cout << "Enter one side your of Square: ";        cin >> side;         area = side * side;        cout << "Area of Square: " << area << "\n";    }      // Virtual Destuctor for every Derived class    virtual ~Square()    {        cout << "Square Destuctor Call\n";    }}; int main(){     // base class pointer    Shape* S;    Rectangle r;     // initialization of reference variable    S = &r;     // calling of Rectangle function    S->calculate();    Square sq;     // initialization of reference variable    S = &sq;     // calling of Square function    S->calculate();     // return 0 to tell the program executed    // successfully    return 0;}
Output:
Enter Width of Rectangle: 10
Enter Height of Rectangle: 20
Area of Rectangle: 200
Enter one side your of Square: 16
Area of Square: 256
What is the use? Virtual functions allow us to create a list of base class pointers and call methods of any of the derived classes without even knowing the kind of derived class object. 
Consider employee management software for an organization.Let the code has a simple base class Employee, the class contains virtual functions like raiseSalary(), transfer(), promote(), etc. Different types of employees like Managers, Engineers, etc., may have their own implementations of the virtual functions present in base class Employee. 
In our complete software, we just need to pass a list of employees everywhere and call appropriate functions without even knowing the type of employee. For example, we can easily raise the salary of all employees by iterating through the list of employees. Every type of employee may have its own logic in its class, but we don’t need to worry about them because if raiseSalary() is present for a specific employee type, only that function would be called.
CPP
// C++ program to demonstrate how a virtual function// is used in a real life scenario class Employee {public:    virtual void raiseSalary()    {        // common raise salary code    }     virtual void promote()    {        // common promote code    }}; class Manager : public Employee {    virtual void raiseSalary()    {        // Manager specific raise salary code, may contain        // increment of manager specific incentives    }     virtual void promote()    {        // Manager specific promote    }}; // Similarly, there may be other types of employees // We need a very simple function// to increment the salary of all employees// Note that emp[] is an array of pointers// and actual pointed objects can// be any type of employees.// This function should ideally// be in a class like Organization,// we have made it global to keep things simplevoid globalRaiseSalary(Employee* emp[], int n){    for (int i = 0; i < n; i++) {        // Polymorphic Call: Calls raiseSalary()        // according to the actual object, not        // according to the type of pointer        emp[i]->raiseSalary();    }}
Like the ‘globalRaiseSalary()‘ function, there can be many other operations that can be performed on a list of employees without even knowing the type of the object instance. Virtual functions are so useful that later languages like Java keep all methods virtual by default.
The compiler maintains two things to serve this purpose:
vtable: A table of function pointers, maintained per class. 
vptr: A pointer to vtable, maintained per object instance (see this for an example). 
The compiler adds additional code at two places to maintain and use vptr.
1. Code in every constructor. This code sets the vptr of the object being created. This code sets vptr to point to the vtable of the class. 
2. Code with polymorphic function call (e.g. bp->show() in above code). Wherever a polymorphic call is made, the compiler inserts code to first look for vptr using a base class pointer or reference (In the above example, since the pointed or referred object is of a derived type, vptr of a derived class is accessed). Once vptr is fetched, vtable of derived class can be accessed. Using vtable, the address of the derived class function show() is accessed and called.
Is this a standard way for implementation of run-time polymorphism in C++? The C++ standards do not mandate exactly how runtime polymorphism must be implemented, but compilers generally use minor variations on the same basic model.
brain56
scripter
architgwl2000
varshagumber28
abhaysasidharan
adarshlondhe19
rohitbadgujar
kziemianfvt
himeshchauhan10
harsh_shokeen
rkbhola5
sumitgumber28
simranarora5sos
themrinmoy
CPP-Functions
cpp-inheritance
cpp-virtual
C++
School Programming
CPP
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Templates in C++ with Examples
Operator Overloading in C++
unordered_map in C++ STL
Socket Programming in C/C++
Queue in C++ Standard Template Library (STL)
Python Dictionary
Reverse a string in Java
Introduction To PYTHON
Interfaces in Java
C++ Data Types