Overview
Polymorphism refers to the ability of a single interface to represent multiple underlying forms or behaviors. In C++, this concept enables a unified interface to handle different data types or object behaviors through a common base class.
Types of Polymorphism
- Static Polymorphism
- Function overloading
- Template programming
- Dynamic Polymorphims
- Virtual functions
Static Polymorphism
Static polymorphism is resolved at compile time.
Function Overloading
Multiple functions with the same name but different paramter types or counts:
int Sum(int x, int y) { return x + y; }
double Sum(double x, double y) { return x + y; }
Template Programming
Templates allow writing generic code that works with various types:
template <typename T>
T SumGeneric(T a, T b) {
return a + b;
}
Example Usage
#include <iostream>
int main() {
int i1 = 3, i2 = 5;
double d1 = 2.5, d2 = 4.5;
std::cout << Sum(i1, i2) << "\n"; // Output: 8
std::cout << Sum(d1, d2) << "\n"; // Output: 7
std::cout << SumGeneric(i1, i2) << "\n"; // Output: 8
std::cout << SumGeneric(d1, d2) << "\n"; // Output: 7
return 0;
}
Dynamic Polymorphism
Dynamic polymorphism is resolved at runtime using virtual functions. This is achieved by declaring virtual funcsions in a base class and overriding them in derived classes.
Base and Derived Classes
#include <vector>
#include <memory>
class Shape {
public:
virtual ~Shape() = default;
virtual void draw() const = 0;
virtual void info() const { }
};
class Circle : public Shape {
public:
void draw() const override {
std::cout << "Drawing a circle\n";
}
};
class Square : public Shape {
public:
void draw() const override {
std::cout << "Drawing a square\n";
}
};
Polymorphic Behavior in Action
int main() {
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>());
shapes.push_back(std::make_unique<Square>());
for (const auto& shape : shapes) {
shape->draw();
}
return 0;
}
Key Points
- Declaring the destructor as virtual ensures proper cleanup of derived objects.
- Pure virtual functions (e.g.,
virtual void draw() const = 0;) make a class abstract and require overriding in derived classes. - The
overridekeyword ensures correct virtual function overriding.
Summary
- Static polymorphism simplifies code through overloading and templates.
- Dynamic polymorphism enables flexible object-oriented designs through virtual functions.