Polymorphism is the ability of objects of different classes to respond to the same function call in different ways. It allows us to perform a single action in different ways based on the actual object type at runtime. Polymorphism promotes code reusability, flexibility, and extensibility in object-oriented programming.
There are two forms of polymorphism in C++: compile-time polymorphism and runtime polymorphism.
Compile-time polymorphism is achieved through function overloading and template specialization. It allows different functions to have the same name but different parameters or behavior based on the arguments passed or the template types used. The compiler determines which function to call based on the function signature at compile-time.
Example of Function Overloading:
#include <iostream>
void display(int num) {
std::cout << "Displaying an integer: " << num << std::endl;
}
void display(double num) {
std::cout << "Displaying a double: " << num << std::endl;
}
int main() {
display(5); // Output: Displaying an integer: 5
display(3.14); // Output: Displaying a double: 3.14
return 0;
}
In this example, we have two functions named display()
that are overloaded based on the types of their parameters. The appropriate function is selected at compile-time based on the arguments passed.
Example of Template Specialization:
#include <iostream>
template<typename T>
void display(T value) {
std::cout << "Displaying a value: " << value << std::endl;
}
template<>
void display<int>(int value) {
std::cout << "Displaying an integer: " << value << std::endl;
}
int main() {
display(3.14); // Output: Displaying a value: 3.14
display(5); // Output: Displaying an integer: 5
return 0;
}
In this example, we have a template function display()
that can accept any type. However, we specialize it for int
type to provide custom behavior. The specialization is selected at compile-time based on the template arguments used.
Runtime polymorphism is achieved through virtual functions and function overriding. It allows objects of derived classes to be treated as objects of the base class, and the appropriate function is called based on the actual object type at runtime. This is also known as late binding or dynamic binding.
Example of Function Overriding:
#include <iostream>
class Animal {
public:
virtual void makeSound() {
std::cout << "Animal makes a sound." << std::endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
std::cout << "Cat meows." << std::endl;
}
};
int main() {
Animal* animalPtr;
Cat cat;
animalPtr = &cat;
animalPtr->makeSound(); // Output: Cat meows.
return 0;
}
In this example, we have a base class Animal
and a derived class Cat
. The Animal
class has a virtual function makeSound()
, which is overridden in the Cat
class.
At runtime, we create an object of the Cat
class and assign its address to a pointer of type Animal*
. When we call the makeSound()
function using the animalPtr
, the appropriate version of the function is called based on the actual object being pointed to. This is determined dynamically at runtime, allowing us to hear the sound of a cat.
Polymorphism allows us to treat objects of derived classes as objects of the base class, while still maintaining their individual behaviors.
In summary, polymorphism is the ability of objects to respond to the same function call in different ways. Compile-time polymorphism is achieved through function overloading and template specialization, while runtime polymorphism is achieved through virtual functions and function overriding.
Function overloading refers to having multiple functions with the same name but different parameters or behavior, allowing the compiler to select the appropriate function at compile-time based on the arguments passed.
Function overriding refers to providing a different implementation of a virtual function in a derived class, allowing the appropriate version of the function to be called dynamically at runtime based on the actual object type.
Both overloading and overriding contribute to polymorphism and help in designing flexible and reusable code.