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 Algorithms, Competitive Programming, JavaScript, SQL, System 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!