Polymorphism in C++ allows us to reuse code by creating one function that’s usable for multiple uses. We can also make operators polymorphic and use them to add not only numbers but also combine strings. This saves time and allows for a more streamlined program.
Polymorphism is considered one of the important features of Object-Oriented Programming. Polymorphism allows us to perform a single action in different ways. In other words, polymorphism allows you to define one interface and have multiple implementations. The word “poly” means many and “morphs” means forms, So it means many forms.
Types of Polymorphism
- Compile-time Polymorphism
- Runtime Polymorphism
1. Compile-Time Polymorphism
Compile-time Polymorphism refers to the mechanism in C++ where the compiler determines which function to call during compilation based on the function’s signature and the context in which it is invoked.
It is also known as static polymorphism. This type of polymorphism is achieved by function overloading or operator overloading.
(Note: But Java doesn’t support the Operator Overloading.)
A. Function Overloading
Function overloading occurs when multiple functions have the same name but different parameters. This enables the same function name to perform various tasks based on the parameters provided, which can vary in number or type.
It’s a feature of object-oriented programming that allows for creating multiple functions with the same name but different parameter lists.
Below is the C++ program to show function overloading or compile-time polymorphism:
#include <iostream>
using namespace std;
class Overload {
public:
void print(int num) {
cout << "Printing integer: " << num << endl;
}
void print(double num) {
cout << "Printing double: " << num << endl;
}
void print(string text) {
cout << "Printing string: " << text << endl;
}
};
int main() {
Overload obj;
obj.print(5);
obj.print(10.5);
obj.print("Hello World");
return 0;
}
== Output==
Printing integer: 5
Printing double: 10.5
Printing string: Hello World
B. Operator Overloading
In C++, operator overloading empowers operators to have special meanings for specific data types. For instance, we can redefine the addition operator (+) for the string class to concatenate two strings. We know that the task of this operator is to add two operands. So a single operator ‘+’, when placed between integer operands, adds them and when placed between string operands, concatenates them. This flexibility allows us to extend the functionality of operators beyond their conventional usage.
Below is the C++ program to demonstrate operator overloading:
#include <iostream>
#include <string>
using namespace std;
class StringConcat {
private:
string str;
public:
StringConcat() : str("") {}
StringConcat(string s) : str(s) {}
StringConcat operator+(const StringConcat& obj) {
StringConcat result;
result.str = this->str + obj.str;
return result;
}
void display() {
cout << "Concatenated String: " << str << endl;
}
};
int main() {
StringConcat str1("Hello");
StringConcat str2("World");
StringConcat result = str1 + str2;
result.display();
return 0;
}
==OUTPIT==
Concatenated String: HelloWorld
2. Runtime Polymorphism
Runtime Polymorphism in C++, also known as late binding or dynamic Polymorphism, is achieved through function overriding. Unlike compile-time Polymorphism, where the function call is resolved at compile time, run time Polymorphism in C++ resolves the function call at runtime.
This allows for greater flexibility as the specific function implementation is determined based on the actual object type during program execution.
A. Function Overriding (Runtime)
Function overriding occurs when a derived class provides a specific implementation for a function already defined in its base class. This allows objects of the derived class to use their version of the function, providing a way to achieve runtime Polymorphism.
Here’s an example demonstrating function overriding in C++ related to car colors:
#include <iostream>
#include <string>
using namespace std;
class Car {
public:
virtual void displayColor() {
cout << "The car is colored in default color." << endl;
}
};
class RedCar : public Car {
public:
void displayColor() override {
cout << "The car is colored red." << endl;
}
};
class BlueCar : public Car {
public:
void displayColor() override {
cout << "The car is colored blue." << endl;
}
};
int main() {
Car* car1 = new RedCar();
Car* car2 = new BlueCar();
car1->displayColor();
car2->displayColor();
delete car1;
delete car2;
return 0;
}
==OUTPUT==
The car is colored red.
The car is colored blue.
B. Virtual Function
A virtual function is a member function declared within a base class that is redefined (or overridden) in a derived class. It allows the derived class to provide its implementation of the function, which is invoked based on the actual object type during runtime.
This enables runtime Polymorphism, where the appropriate function implementation is selected dynamically based on the object’s type rather than statically at compile time.
Key Points To Remember:
- Virtual functions are declared using the virtual keyword in the base class.
- They are overridden in derived classes using the override keyword.
- Virtual functions enable dynamic binding, where the call is resolved at runtime.
- They allow for polymorphic behavior, where objects of different derived classes can be treated uniformly through a standard interface.
Example: Car Brands
#include <iostream>
#include <string>
using namespace std;
class Car {
public:
virtual void displayBrand() {
cout << "This is a generic car." << endl;
}
};
class Ford : public Car {
public:
void displayBrand() override {
cout << "This is a Ford car." << endl;
}
};
class Toyota : public Car {
public:
void displayBrand() override {
cout << "This is a Toyota car." << endl;
}
};
int main() {
Car* car1 = new Ford();
Car* car2 = new Toyota();
car1->displayBrand();
car2->displayBrand();
delete car1;
delete car2;
return 0;
}
==OUTPUT==
This is a Ford car.
This is a Toyota car.
What is the difference between Runtime & Compile-Time ? Read More
Pingback: MSCCS-103 (Assignment : July-2023, Jan-2024) – RajCTU