In object-oriented programming, polymorphism means assigning a different meaning to particular symbols or functions (with same name) in other contexts.
‘Polymorphism’ is the same thing that behaves differently in different situations. Consider you as one object having a talking behaviour. Your parents or friends will execute the same behaviour/action differently.
To be concise, polymorphism means an ability to perform more than one task.
It allows us to have more than one functions with the same name in a program. Polymorphism is an essential feature of C++.
Polymorphism is categorised into two types. The figure below shows the types:
Compile Time Polymorphism
In compile-time polymorphism, a function is called at the time of program compilation. We call this type of polymorphism as early binding or Static binding.
Function overloading and operator overloading is the type of Compile time polymorphism.
I. Function Overloading
Function overloading means one function can perform many tasks. In C++, a single function is used to perform many tasks with the same name and different types of arguments. In the function overloading function will call at the time of program compilation. It is an example of compile-time polymorphism.
In the below example, A function ADD() is used to perform two tasks. The two asks would be to add two integer values and add two strings (concatenate).
Readability of the program increases by function overloading. It is achieved by using the same name for the same action.
Source Code:-
#include <iostream> using namespace std; class Addition { public: int ADD(int X,int Y) // Function with parameter { return X+Y; // this function is performing addition of two Integer value } int ADD() { // Function with same name but without parameter string a= "HELLO"; string b="SAM"; // in this function concatenation is performed string c= a+b; cout<<c<<endl; } }; int main(void) { Addition obj; // Object is created cout<<obj.ADD(128, 15)<<endl; //first method is called obj.ADD(); // second method is called return 0; }
Output
143
HELLOSAM
In the above example, we use function ADD() to perform many tasks which is a property of polymorphism.
II.Operator Overloading
Operator overloading means defining additional tasks to operators without changing its actual meaning. We do this by using operator function.
The purpose of operator overloading is to provide a special meaning to the user-defined data types.
The advantage of Operators overloading is to perform different operations on the same operand.
Source Code
#include <iostream> using namespace std; class A { string x; public: A(){} A(string i) { x=i; } void operator+(A); void display(); }; void A:: operator+(A a) { string m = x+a.x; cout<<"The result of the addition of two objects is : "<<m; } int main() { A a1("Welcome"); A a2("back"); a1+a2; return 0; }
Output
The result of the addition of two objects is: Welcomeback
Runtime Polymorphism
In a Runtime polymorphism, functions are called at the time the program execution. Hence, it is known as late binding or dynamic binding.
Function overriding is a part of runtime polymorphism. In function overriding, more than one method has the same name with different types of the parameter list.
It is achieved by using virtual functions and pointers. It provides slow execution as it is known at the run time. Thus, It is more flexible as all the things executed at the run time.
I. Function overriding
In function overriding, we give the new definition to base class function in the derived class. At that time, we can say the base function has been overridden. It can be only possible in the ‘derived class’. In function overriding, we have two definitions of the same function, one in the superclass and one in the derived class. The decision about which function definition requires calling happens at runtime. That is the reason we call it ‘Runtime polymorphism’.
Source code
#include <iostream> using namespace std; class Animal { public: void function(){ cout<<"Eating..."<<endl; } }; class Man: public Animal { public: void function() { cout<<"Walking ..."<<endl; } }; int main(void) { Animal A =Animal(); A.function(); //parent class object Man m = Man(); m.function(); // child class object return 0; }
Output
Eating …..
Walking……
II. Virtual Function
A virtual function is declared by keyword virtual. The return type of virtual function may be int, float, void.
A virtual function is a member function in the base class. We can redefine it in a derived class. It is part of run time polymorphism. The declaration of the virtual function must be in the base class by using the keyword virtual. A virtual function is not static.
The virtual function helps to tell the compiler to perform dynamic binding or late binding on the function.
If it is necessary to use a single pointer to refer to all the different classes’ objects. This is because we will have to create a pointer to the base class that refers to all the derived objects.
But, when the base class pointer contains the derived class address, the object always executes the base class function. For resolving this problem, we use the virtual function.
When we declare a virtual function, the compiler determines which function to invoke at runtime.
Let’s see the below example for understanding how the program execution happens without virtual function and with virtual function.
Source code
//without virtual Function #include <iostream> using namespace std; class Add { int x=5, y=20; public: void display() //overridden function { cout << "Value of x is : " << x+y<<endl; } }; class Substract: public Add { int y = 10,z=30; public: void display() //overridden function { cout << "Value of y is : " <<y-z<<endl; } }; int main() { Add *m; //base class pointer .it can only access the base class members Substract s; // making object of derived class m = &s; m->display(); // Accessing the function by using base class pointer return 0; }
Output
Value of x is: 25
Virtual Function used to invoke the derived class in a program.
Source Code
#include<iostream> using namespace std; class Add { public: virtual void print () { int a=20, b=30; cout<< " base class Action is:"<<a+b <<endl; } void show () { cout<< "show base class" <<endl; } }; class Sub: public Add { public: void print () //print () is already virtual function in derived class, we could also declared as virtual void print () explicitly { int x=20,y=10; cout<< " derived class Action:"<<x-y <<endl; } void show () { cout<< "show derived class" <<endl; } }; //main function int main() { Add *aptr; Sub s; aptr = &s; //virtual function, binded at runtime (Runtime polymorphism) aptr->print(); // Non-virtual function, binded at compile time aptr->show(); return 0; }
Output
derived class Action:10
show base class
Pure virtual Function
When the function has no definition, we call such functions as “Do-nothing function or Pure virtual function”. The declaration of this function happens in the base class with no definition.
Source Code
#include <iostream> using namespace std; class Animal { public: virtual void show() = 0; //Pure virtual function declaration. }; class Man: public Animal { public: void show() { cout << "Man is the part of animal husbandry " << endl; } }; int main() { Animal *aptr; //Base class pointer //Animal a; Man m; //derived class object creation. aptr = &m; aptr->show(); return 0; }
Output
Man is the part of animal husbandry
This brings us to end of the blog on Polymorphism in C++. Hope this helps you to up-skill your C++ skills. To learn more about programming and other related concepts, check out the courses on Great Learning Academy.
Also, if you are preparing for Interviews, check out these Interview Questions for C++ to ace it like a pro.
0