Polymorphism in C++
Polymorphism in C++
Polymorphism in C++ basically means having multiple existent forms in the program, A simple code may behave differently in different situations. For example, we have only one identity, to some we are friends, or father, student, employee etc.
How Polymorphism works in C++
In C++, polymorphism, generally happens because of classes objects and events are related with inheritance and hierarchy. Lets see what’s polymorphism in detail below –
Polymorphism is of two types –
- Compile time polymorphism (demonstrates static/early binding)
- Function Overloading
- Operator Overloading
- Run time polymorphism (demonstrates dynamic/late binding)
- Function Overriding (Achieved with help of virtual keyword)
Compile Time Polymorphism
Function Overloading
This happens when in a given program there are multiple functions with the same name but different arguments inside it or different parameters.
For example –
#include <iostream> using namespace std; class myClass { public: void myFunction(int a) { cout << "Accepted integer value " << a << endl; } void myFunction(double a) { cout << "Accepted double value " << a << endl; } void myFunction(int a, int b) { cout << "Accepted multiple values, Value1:" << a << endl; cout << "Accepted multiple values, Value2:" << b << endl; } }; int main() { myClass myclassObj; // will go to function with int as passed on variable as value passed is int type myclassObj.myFunction(5); // will go to function with double myclassObj.myFunction(500.263); // will go to function with multiple parameters myclassObj.myFunction(5,3); return 0; }
Output –
Accepted integer value 5 Accepted double value 500.263 Accepted multiple values, Value1: 5 Accepted multiple values, Value2: 3
Now, in the above, the functions go to their correct argument type in myClass this is called function overloading.
2. Pointer * vs Array int fun(int *ptr); || int fun(int ptr[]); // redeclaration of fun(int *ptr) can't be overloaded.
Operator Overloading
Operator overloading is possible in C++, you can change the behaviour of an operator like +, -, & etc to do different things.
- For example, you can use + to concatenate two strings.
- Consider two strings s1 and s2, we can concatenate two strings s1 and s2 by overloading + operator as String s, s = s1 + s2;
For Example – We know that ++x increments the value of x by 1. What if we want to overload this and increase the value by 100. The program below does that.
#include <iostream> using namespace std; class Test { private: int count; public: Test(): count(101) { //writing fuction name followed by data member and passed on value works like constructor // Test(): count(101) same as writing count = 101; here } // we write operator before overloading such operators void operator ++() { count = count+100; } void Display() { court << "Count: " << count; } }; int main() { Test t; // this calls "function void operator ++()" function ++t; t.Display(); return 0; }
Output
201
Operators that can be overloaded –
+ | – | * | / | % | ^ |
& | | | ~ | ! | , | = |
< | > | <= | >= | ++ | — |
<< | >> | == | != | && | || |
+= | -= | /= | %= | ^= | &= |
|= | *= | <<= | >>= | [] | () |
-> | ->* | new | new [] | delete | delete [] |
Operators that can’t be overloaded –
:: | .* | . | ?: |
Runtime Polymorphism
There are two ways run time polymorphism may be achieved in C++
- Function Overriding
- Virtual Functions (Solves the problem of static resolution while working with pointers)
Note – This information is given wrong on Gks4Gks and tut point they have explained virtual functions instead at first.
Runtime Polymorphism using Function Overriding
In a case when a function is declared in both the parent class(Base Class) and child class(Derived Class).
- To decide upon which function has to be called, the program will only know at the run time.
- Let us look at the very simple program below to understand the basic
#include <iostream> using namespace std; // This is Parent class class Parent { public: void print() { cout << "Parent Class printing" << endl; } }; // This is Child class class Child : public Parent { public: // as we see that it is already declared in the parent function void print() { cout << "Child Class printing" << endl; } }; int main() { //Creating object for parent class Parent parent_object; //Creating object for child class //No need to get conused here its same as Child object2; //We are just called a default constructor Child child_object = Child(); // This will go to the parent member function parent_object.print(); // This will however, go to child member function // overrides the parent function as the object is of the child class child_object.print(); return 0; }
Output
Parent Class printing Child Class printing
What exactly happens at the backend?
Even though, the child class has inherited all the functions of the parent class and has the same function definition within itself. The call is made to function of the child class as the object is of the child class.
Runtime Polymorphism using Virtual Function
- What if we create a pointer to the parent class
- And assign it to the address of the base class object
Something such as this –
Parent *parent_object; Child child_object; parent_object = &child_object;
Now, we will expect the function called by parent_object to call the child object function right? Because the final address is pointed toward child_object location. Let us see what happens –
Code
#include <iostream> using namespace std; // This is Parent class class Parent { public: void print() { cout << "Parent Class printing" << endl; } }; // This is Child class class Child : public Parent { public: // as we see that it is already declared in the parent function void print() { cout << "Child Class printing" << endl; } }; int main() { Parent *parent_object; Child child_object; parent_object = &child_object; // catch of the program is here // also as we are dealing with pointers instead of . we need to use -> parent_object->print(); // In the above program instead of using pointers we can write // Parent parent_object = Child(); // parent_object.print(); // this would also give same results return 0; }
Output
Parent Class printing
But, this instance is a classic example of early binding as the print() function is set during the compilation of the program. The definition of C++ is written, forces this static call and is also called as static resolution.
Thus, the above is an example of Compile time polymorphism. Also known as early binding.
Forcing Runtime Polymorphism using Virtual function
If we add a virtual keyword before the function in the parent(base) class we can force runtime polymorphism (Late binding). Let us look with the code below –Code
#include <iostream> using namespace std; // This is Parent class class Parent { public: // adding virtual keyword here virtual void print() { cout << "Parent Class printing" << endl; } }; // This is Child class class Child : public Parent { public: // as we see that it is already declared in the parent function void print() { cout << "Child Class printing" << endl; } }; int main() { Parent *parent_object; Child child_object; parent_object = &child_object; // catch of the program is here // also as we are dealing with pointers instead of . we need to use -> parent_object->print(); return 0; }
Output
Child Class printing
This is called as late binding at runtime, thus runtime polymorphism is implemented. We solved the problem of static resolution which had earlier forced early binding(Compile time polymorphism)
Prime Course Trailer
Related Banners
Get PrepInsta Prime & get Access to all 200+ courses offered by PrepInsta in One Subscription
Get over 200+ course One Subscription
Courses like AI/ML, Cloud Computing, Ethical Hacking, C, C++, Java, Python, DSA (All Languages), Competitive Coding (All Languages), TCS, Infosys, Wipro, Amazon, DBMS, SQL and others
Login/Signup to comment