The word Polymorphism means "many forms." In C++, it occurs when there is a hierarchy of classes related by inheritance. It allows us to perform a single action in different ways.
There are two main types:
Compile-time Polymorphism: (Function Overloading) Multiple functions with the same name but different parameters.
Runtime Polymorphism: (Function Overriding) A child class provides a specific implementation of a method that is already defined in its parent class.
1. Function Overriding
When a child class doesn't like how the parent does something, it "overrides" that function with its own version. To do this properly in C++, we use the virtual keyword in the parent class.
Code Example: The Animal Sound System
Even though we treat all animals as the generic "Animal" type, polymorphism ensures the correct sound is made.
#include <iostream>
using namespace std;
// Base Class
class Animal {
public:
// 'virtual' tells C++: "Look for an overridden version in child classes"
virtual void makeSound() {
cout << "The animal makes a sound" << endl;
}
};
// Derived Class 1
class Dog : public Animal {
public:
void makeSound() override { // 'override' is good practice to show intent
cout << "The dog says: Woof! Woof!" << endl;
}
};
// Derived Class 2
class Cat : public Animal {
public:
void makeSound() override {
cout << "The cat says: Meow!" << endl;
}
};
int main() {
// We can use a Parent pointer to point to Child objects
Animal* myDog = new Dog();
Animal* myCat = new Cat();
// Even though these are 'Animal' pointers, they call the specific sounds
myDog->makeSound(); // Outputs: Woof! Woof!
myCat->makeSound(); // Outputs: Meow!
// Cleanup
delete myDog;
delete myCat;
return 0;
}Why is this useful?
Imagine you are making a game with a list of 100 different enemies (Orc, Goblin, Dragon). With polymorphism, you can put them all in one array of Enemy* and call enemy->attack() in a single loop. You don't need to know which specific enemy it is; C++ handles the "many forms" for you!