Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
What is overriding?
3.
Early Binding
4.
Late Binding
5.
Virtual Functions
6.
Pure Virtual Functions
7.
Virtual Destructors
8.
Frequently Asked Questions 
8.1.
Why is runtime polymorphism called so?
8.2.
How many types of polymorphism are there in C++?
8.3.
Can virtual functions be private in C++?
9.
Conclusion
Last Updated: Mar 27, 2024
Medium

Virtual Functions & Runtime Polymorphism in C++

Author Urwashi Priya
0 upvote

Introduction

The virtual functions concept is used to achieve runtime polymorphism in C++. The problem of function overriding leads to this concept. So, Let’s understand the problem and solutions to it in deep.

Fibonacci Series in C++
 

What is overriding?

Method overriding is a way of declaring a method in the subclass which is already present in the parent class is known. Overriding is done when a child class wants to do something to which is done in the parent class. Now, the method in the parent class is called the overridden method and the method in the child class is called overriding method. When a derived class object is created and the function is called the compiler gets confused to execute which function (either base or derived), it then executes the derived class method. To avoid function overriding, we use virtual keyword.

Example

include < iostream >
using namespace std;
class Base
{
 	public: void show_val() {
   		cout << “Class::Base” << endl;
 	}
};
class Derived: public Base {
 	public: void show_val() //function overridden from base
 	{
   		cout << “Class::Derived” << endl;
 	}
};
int main() {
 	Base b;
 	Derived d;
 	b.show_val();
}
You can also try this code with Online C++ Compiler
Run Code

Output


Class:: Base
Class:: Derived
You can also try this code with Online C Compiler
Run Code

Facts:

  • Function overloading is an example of compile-time polymorphism
  • Function overriding is an example of run time polymorphism

Early Binding


This is compile-time polymorphism. Here, it directly associates an address to the function call. For function overloading, it is an example of early binding.

Example

include < iostream >
using namespace std;
class Base {
 	public: void display() {
   		cout << ”In Base class” << endl;
 	}
};
class Derived: public Base {
 	public: void display() {
   		cout << “In Derived class” << endl;
 	}
};
int main(void) {
 	Base * base_pointer = new Derived;
 	base_pointer -> display();
 	return 0;
}
d.show_val();
}
You can also try this code with Online C++ Compiler
Run Code

 

Output

In Base class
You can also try this code with Online C Compiler
Run Code


Also, see Literals in C.

Late Binding


This is run time polymorphism. In this type of binding, the compiler adds code that identifies the object type at runtime then matches the call with the right function definition. This is achieved by using the virtual function.

Example

include < iostream >
using namespace std;
class Base {
 	public: virtual void display() {
   		cout << “In Base class” << endl;
 	}
};
class Derived: public Base {
 	public: void display() {
   		cout << “In Derived class” << endl;
 	}
};
int main() {
 	Base * base_pointer = new Derived;
 	base_pointer -> display();
 	return 0;
}
d.show_val();
}
You can also try this code with Online C++ Compiler
Run Code

 

Output

In Derived class
You can also try this code with Online C++ Compiler
Run Code

 

Virtual Functions


A virtual function is a member function of a base class which is redefined in the derived class. It is achieved by using the keyword ‘virtual’ in the base class. The function call is decided on the type of referred object not according to the type of pointer.

Rules for Virtual Functions:

  • Virtual functions cannot be static and friend to another class
  • Virtual functions must be accessed using pointers or references of base class type
  • The function prototype should be same in both base and derived classes
  • A class must not have a virtual constructor. But it can have a virtual destructor
  • They are always defined in the base class and redefined in the derived class

Example

include < iostream >
using namespace std;
class base {
 	public: virtual void print() {
   		cout << “print base class” << endl;
 	}
 	void show()
 	{
   		cout << “show base class” << endl;
 	}
};
class derived: public base {
 	public: void print() {
   		cout << “print derived class” << endl;
 	}
 	void show() {
   		cout << “show derived class” << endl;
 	}
};
int main() {
 	base * bptr;
 	derived d;
 	bptr = & d;
 	// virtual function, binded at runtime
 	bptr -> print();
 	// Non-virtual function, binded at compile time
 	bptr -> show();
}
d.show_val();
}
You can also try this code with Online C++ Compiler
Run Code

 

Output:


print derived class
show base class
You can also try this code with Online C++ Compiler
Run Code

Explanation: Runtime polymorphism is achieved only through a pointer (or reference) of base class type. Also, a base class pointer can point to the objects of the base class as well as to the objects of the derived class. In the above code, base class pointer ‘bptr’ contains the address of object ‘d’ of the derived class.
Late binding(Runtime) is done in accordance with the content of pointer (i.e. location pointed to by pointer) and Early binding (Compile-time) is done according to the type of pointer since print() function is declared with the virtual keyword so it will be bound at run-time (output is print derived class as a pointer is pointing to object of derived class ) and show() is non-virtual so it will be bound during compile time(output is show
base class as a pointer is of base type).


NOTE: If we have created a virtual function in the base class and it is being overridden in the derived class then we don’t need virtual keyword in the derived class, functions are automatically considered as virtual functions in the derived class.

Pure Virtual Functions


A pure virtual function is a virtual function in C++ for which we need not write any function definition and only we have to declare it. It is declared by assigning 0 in the declaration. An abstract class is a class in C++ which have at least one pure virtual function.

An abstract class can have normal functions and variables along with a pure virtual function.

  • An abstract class cannot be instantiated, but pointers and references of Abstract class type can be created
  • Abstract classes are mainly used for Upcasting so that its derived classes can use their interface
  • If an Abstract Class has derived class, they must implement all pure virtual functions, or else they will become Abstract too
  • We can’t create an object of abstract class as we reserve a slot for a pure virtual function in Vtable, but we don’t put any address, so Vtable will remain incomplete

Example

include < iostream >
using namespace std;
class B {
 public: virtual void s() = 0; // Pure Virtual Function
};
class D: public B {
 public: void s() {
   cout << “Virtual Function in Derived class\ n”;
 }
};
You can also try this code with Online C++ Compiler
Run Code


Output

Virtual Function in Derived class
You can also try this code with Online C++ Compiler
Run Code

 

Virtual Destructors


Destructors of the class can be declared as virtual. Whenever we do upcast i.e. assigning the derived class object to a base class pointer, the ordinary destructors can produce unacceptable results.

For Example, consider the following upcasting of the ordinary destructor.

include < iostream >
using namespace std;
class Base {
 public:
   ~Base() {
     cout << “Base Class::Destructor\ n”;
   }
};
class Derived: public Base {
 public:
   ~Derived() {
     cout << “Derived class::Destructor\ n”;
   }
};
int main() {
 Base * b = new Derived; // Upcasting
 delete b;
}
b -> s();
}
You can also try this code with Online C++ Compiler
Run Code

 

Output

Base Class:: Destructor
You can also try this code with Online C++ Compiler
Run Code

In the above program, we have an inherited derived class from the base class. In the main, we assign an object of the derived class to a base class pointer. Ideally, the destructor that is called when “delete b” is called should have been that of derived class but we can see from the output that destructor of the base class is called as base class pointer points to that.
 

Due to this, the derived class destructor is not called and the derived class object remains intact thereby resulting in a memory leak. The solution to this is to make base class constructor virtual so that the object pointer points to correct destructor and proper destruction of objects is carried out.

The use of virtual destructor is shown in the below example.

include < iostream >
using namespace std;
class Base {
 public: virtual~Base() {
   cout << “Base Class::Destructor\ n”;
 }
};
class Derived: public Base {
 public:
   ~Derived() {
     cout << “Derived class::Destructor\ n”;
   }
};
int main() {
 Base * b = new Derived; // Upcasting
 delete b;
}
You can also try this code with Online C++ Compiler
Run Code

 

Output

Derived class:: Destructor
Base Class:: Destructor
You can also try this code with Online C++ Compiler
Run Code

To read more on C++, click here.

Check out this article - Compile Time Polymorphism

Frequently Asked Questions 

Why is runtime polymorphism called so?

This is because subclass methods get invoked during runtime.

How many types of polymorphism are there in C++?

There are two types of polymorphism in C++. They are run-time polymorphism and compile-time polymorphism.

Can virtual functions be private in C++?

Yes, virtual functions can be private in C++ as C++ supports access control.  

Conclusion

This article extensively discusses Virtual Functions & Runtime Polymorphism in C++.

Recommended Readings:

You can refer to our Guided Path on Coding Ninjas Studio to upskill yourself in Data Structures and AlgorithmsCompetitive ProgrammingJavaScriptSQLSystem Design, and many more!
If you want to test your competency in coding, you may check out the Mock Test Series and participate in the Contests organized on Coding Ninjas Studio! But if you have just started your learning process and are looking for questions asked by tech giants like Amazon, Microsoft, Uber, etc; you must look at the Problems, Interview Experiences, and Interview Bundle for placement preparations.

Nevertheless, you may consider our Courses to give your career an edge over others!

Do upvote our blog to help other ninjas grow. 

Happy Coding!    

Live masterclass