Polymorphism is defined as the process of using a function or an operator for more than one purpose. In other words, we can also say that an operator or a function can serve us in different ways.
For example
Let us say an operator '+' is used to add two integer numbers and it is also used to concatenate two strings.
Hence the '+' operator serves two purposes - adding and concatenation.
Now let us learn about types of polymorphism in C++.
Compile-time polymorphism
It is defined as the polymorphism in which the function is called at the compile time. This type of process is also called as early or static binding.
Examples of compile-time polymorphism
1) Function overloading
Function overloading is defined as using one function for different purposes. Here, one function performs many tasks by changing the function signature(number of arguments and types of arguments). It is an example of compile-time polymorphism because what function is to be called is decided at the time of compilation.
Example
In the below code, we have taken a class Addition that performs the addition of two numbers and concatenates two strings. It has a function ADD that is overloaded two times.
The function ADD(int X, int Y) adds two integers and the function ADD with no arguments performs string concatenation.
#include <iostream>
using namespace std;
class Addition { // Create Addition class
public:
int ADD(int X, int Y) // Add function add two numbers
{
return X + Y; // return the Addition of two numbers
}
int ADD()
{ // this ADD function concatenates two strings
string a = "HELLO";
string b = " JAVACPPTUTORIAL";
string c = a + b; // concatenate two strings
cout << c << endl; // print result
}
};
int main(void)
{
Addition obj; // Object is created of Addition class
cout << obj.ADD(120, 105) << endl; //first method is called to add two integers
obj.ADD(); // second method is called to concatenate two strings
return 0;
}
Output
225
HELLO JAVACPPTUTORIAL
Operator Overloading
Operator overloading is defined as using an operator for an addition operation besides the original one.
The concept of operator overloading is used as it provides special meanings to the user-defined data types. The benefit of operator overloading is we can use the same operand to serve two different operations. The basic operator overloading example is the '+' operator as it is used to add numbers and strings.
The operators , :: ?: sizeof cant be overloaded.
Example
In the below example, we have overloaded '+' to add two strings.
An operator is overloaded by using the operator keyword with the operator to be overloaded.
#include <bits/stdc++.h>
using namespace std;
class A // Create a class A
{
string x; // private data member x
public:
A() {}
A(string i)
{
x = i; // Assign the data member
}
void operator+(A); // operator overloading
};
void A::operator+(A a) // concetenate the strings and print output
{
string m = x + a.x;
cout << "The result of the addition of two objects is: " << m;
}
int main()
{
A a1("Welcome "); // string 1
A a2("to javacpptutorial"); // string 2
a1 + a2; // concetenate two strings using operator overloading
return 0;
}
Output
The result of the addition of two objects is: Welcome to javacpptutorial
Run-time polymorphism
The run-time polymorphism is defined as the process in which the function is called at the time of program execution.
An example of runtime polymorphism is function overriding.
Function overriding
When we say a function is overridden it means that a new definition of that function is given in the derived class. Thus, in function overriding, we have two definitions of one in the base class and the other in the derived class. The decision of choosing a function is decided at the run time.
Example
In the below example, a class animal has a function f which is also in the derived class Man. When we call the function f with the base object, it prints the contents of the base and with the derived object the content of the derived. Thus, choosing the function f is decided on runtime.
#include <iostream>
using namespace std;
class Animal { // Create a new class
public:
void f()
{ // the function f will be overriden in the class Man
cout << "Eating..." << endl;
}
};
class Man : public Animal // Base class inheriting derived class
{
public:
void f() // The function f being overriden
{
cout << "Walking ..." << endl;
}
};
int main(void)
{
Animal A = Animal();
A.f(); //parent class object
Man m = Man();
m.f(); // child class object
return 0;
}
Output
Eating...
Walking ...