
Polymorphism in C++ | OOP Tutorial with Real-Life Examples
Polymorphism is one of the four core concepts of Object-Oriented Programming (OOP), along with encapsulation, inheritance, and abstraction. The term polymorphism is derived from two Greek words; poly (many) and morph (forms). In programming, it means one name, many forms. In simple words, polymorphism allows a single function, operator, or object to behave differently based on the context. This makes our code flexible, reusable, and easy to extend.
Understanding Polymorphism
Contents
- Understanding Polymorphism
- What Is Polymorphism in C++
- Types of Polymorphism in C++
- Compile-Time (Static) Polymorphism
- Function Overloading Example
- Operator Overloading Example
- Run-Time (Dynamic) Polymorphism
- Function Overriding Example
- Why Do We Use Pointers in Polymorphism?
- Difference Between Function Overloading and Function Overriding
- Real-World Example: Draw Function
- Advantages of Polymorphism
- Key Points to Remember
- Share this:
- Like this:
- Related
Think about the word “drive”.
A car drives, a bike drives, and a bus drives. The action “drive” is the same, but the behavior is different depending on the object. This is polymorphism; the same operation acting differently for different entities.
Similarly, in a company, the manager, designer, and developer all respond to the command “Work!”, but each performs a different task. This is how polymorphism works in real life and also in programming.
What Is Polymorphism in C++
Polymorphism in C++ is the ability of a function, operator, or object to take many forms. It allows the same function name to perform different tasks depending on the type of object or the number of parameters. Polymorphism provides the foundation for dynamic behavior in software, allowing us to write programs that can adapt at runtime.
Types of Polymorphism in C++
C++ supports two main types of polymorphism:
Type | Description | Example |
---|---|---|
Compile-Time Polymorphism (Static) | Decided by the compiler during compilation. | Function Overloading, Operator Overloading |
Run-Time Polymorphism (Dynamic) | Decided during program execution. | Virtual Functions / Function Overriding |
Compile-Time (Static) Polymorphism
Compile-time polymorphism means the decision about which function to call is made before the program runs. This is achieved using function overloading and operator overloading.
Function Overloading Example
#include <iostream>
using namespace std;
class Math {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
};
int main() {
Math m;
cout << "Sum of two integers: " << m.add(2, 3) << endl;
cout << "Sum of two doubles: " << m.add(2.5, 3.8) << endl;
cout << "Sum of three integers: " << m.add(1, 2, 3) << endl;
return 0;
}
Operator Overloading Example
#include <iostream>
using namespace std;
class Complex {
int real, imag;
public:
Complex(int r = 0, int i = 0) {
real = r;
imag = i;
}
Complex operator + (Complex obj) {
Complex temp;
temp.real = real + obj.real;
temp.imag = imag + obj.imag;
return temp;
}
void display() {
cout << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(3, 2), c2(1, 7);
Complex c3 = c1 + c2; // '+' is overloaded
c3.display();
return 0;
}
Run-Time (Dynamic) Polymorphism
Run-time polymorphism means the function that gets executed is determined at runtime, not compile time. This is achieved through function overriding using virtual functions and pointers/references to base classes.
Function Overriding Example
#include <iostream>
using namespace std;
class Animal {
public:
virtual void sound() {
cout << "Animal makes a sound" << endl;
}
};
class Dog : public Animal {
public:
void sound() {
cout << "Dog barks" << endl;
}
};
class Cat : public Animal {
public:
void sound() {
cout << "Cat meows" << endl;
}
};
int main() {
Animal* a; // Base class pointer
Dog d;
Cat c;
a = &d;
a->sound(); // Calls Dog’s sound()
a = &c;
a->sound(); // Calls Cat’s sound()
return 0;
}
Why Do We Use Pointers in Polymorphism?
When we call a virtual function using an object (e.g., obj.sound()
), the compiler already knows its type, so it doesn’t check at runtime. But when we call it through a base class pointer or reference, C++ checks which object the pointer actually refers to and calls the correct version. Hence, pointers or references are used to achieve real dynamic behavior.
Difference Between Function Overloading and Function Overriding
Feature | Function Overloading | Function Overriding |
---|---|---|
Type | Compile-time polymorphism | Run-time polymorphism |
Parameters | Must differ | Must be same |
Inheritance | Not required | Required |
Keyword | No keyword needed | Uses virtual keyword |
Execution Time | Decided at compile time | Decided at runtime |
Real-World Example: Draw Function
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() {
cout << "Drawing a shape" << endl;
}
};
class Circle : public Shape {
public:
void draw() {
cout << "Drawing a circle" << endl;
}
};
class Rectangle : public Shape {
public:
void draw() {
cout << "Drawing a rectangle" << endl;
}
};
int main() {
Shape* shape;
Circle c;
Rectangle r;
shape = &c;
shape->draw();
shape = &r;
shape->draw();
return 0;
}
Output:
Drawing a circle
Drawing a rectangle
Advantages of Polymorphism
- Code Reusability: Once a base class or function is written, it can be reused by derived classes without rewriting code. This reduces redundancy and saves development time.
- Flexibility: Polymorphism allows one interface to handle multiple types of behavior. For example, a single pointer of a base class can call different functions depending on which derived object it points to.
- Scalability: New classes and behaviors can be added easily without modifying existing code. This makes software easier to extend and maintain.
- Readability: Code becomes more organized and easier to understand since similar actions are grouped under the same interface or function name.
Key Points to Remember
- Polymorphism = One interface, many implementations.
- Function Overloading and Operator Overloading → Compile-time polymorphism.
- Function Overriding using
virtual
→ Run-time polymorphism. - Use base class pointers or references to achieve dynamic behavior.
- Destructors in base classes should be declared
virtual
to ensure proper cleanup.
Aspect | Compile-Time | Run-Time |
---|---|---|
How it happens | Function/Operator Overloading | Virtual Functions |
Decision Time | Before program runs | During program execution |
Keyword | None | virtual |
Inheritance needed | No | Yes |
Binding Type | Early binding | Late binding |
9 thoughts on “Polymorphism in C++ | OOP Tutorial with Real-Life Examples”
**sugarmute**
sugarmute is a science-guided nutritional supplement created to help maintain balanced blood sugar while supporting steady energy and mental clarity.
**glpro**
glpro is a natural dietary supplement designed to promote balanced blood sugar levels and curb sugar cravings.
**prodentim**
prodentim an advanced probiotic formulation designed to support exceptional oral hygiene while fortifying teeth and gums.
**vitta burn**
vitta burn is a liquid dietary supplement formulated to support healthy weight reduction by increasing metabolic rate, reducing hunger, and promoting fat loss.
**synaptigen**
synaptigen is a next-generation brain support supplement that blends natural nootropics, adaptogens
**zencortex**
zencortex contains only the natural ingredients that are effective in supporting incredible hearing naturally.
**yusleep**
yusleep is a gentle, nano-enhanced nightly blend designed to help you drift off quickly, stay asleep longer, and wake feeling clear.
**nitric boost**
nitric boost is a dietary formula crafted to enhance vitality and promote overall well-being.
**glucore**
glucore is a nutritional supplement that is given to patients daily to assist in maintaining healthy blood sugar and metabolic rates.