C++ Polymorphism
What is Polymorphism?
Polymorphism means "many forms" — the same function name behaves differently depending on the object it's called on. C++ supports two types:
- Compile-time (static) — function overloading, operator overloading. Resolved at compile time.
- Runtime (dynamic) — virtual functions. Resolved at runtime via vtable.
Runtime Polymorphism — virtual Functions
Mark a base class method as virtual to allow derived classes to override it. Use a base class pointer/reference to call the correct derived version at runtime.
#include <iostream>
using namespace std;
class Shape {
public:
virtual double area() const { // virtual — can be overridden
return 0.0;
}
virtual void describe() const {
cout << "I am a shape with area: " << area() << endl;
}
virtual ~Shape() {} // virtual destructor — ALWAYS add for base classes
};
class Circle : public Shape {
double radius;
public:
Circle(double r) : radius(r) {}
double area() const override { // override keyword (C++11) — compile-time check
return 3.14159 * radius * radius;
}
};
class Rectangle : public Shape {
double w, h;
public:
Rectangle(double w, double h) : w(w), h(h) {}
double area() const override { return w * h; }
};
class Triangle : public Shape {
double base, height;
public:
Triangle(double b, double h) : base(b), height(h) {}
double area() const override { return 0.5 * base * height; }
};
int main() {
// Base class pointer — runtime polymorphism
Shape *shapes[] = {
new Circle(5),
new Rectangle(4, 6),
new Triangle(3, 8)
};
for (Shape *s : shapes) {
s->describe(); // calls correct area() for each type
delete s;
}
return 0;
}
/*
Output:
I am a shape with area: 78.5397
I am a shape with area: 24
I am a shape with area: 12
*/
Operator Overloading
C++ lets you redefine how operators (+, -, <<, etc.) work for your custom types.
#include <iostream>
using namespace std;
class Vector2D {
public:
double x, y;
Vector2D(double x = 0, double y = 0) : x(x), y(y) {}
// Overload +
Vector2D operator+(const Vector2D &other) const {
return Vector2D(x + other.x, y + other.y);
}
// Overload ==
bool operator==(const Vector2D &other) const {
return x == other.x && y == other.y;
}
// Overload << for cout (friend function)
friend ostream& operator<<(ostream &os, const Vector2D &v) {
os << "(" << v.x << ", " << v.y << ")";
return os;
}
};
int main() {
Vector2D v1(1, 2), v2(3, 4);
Vector2D v3 = v1 + v2;
cout << "v1 = " << v1 << endl; // (1, 2)
cout << "v2 = " << v2 << endl; // (3, 4)
cout << "v1+v2 = " << v3 << endl; // (4, 6)
cout << boolalpha << (v1 == v2) << endl; // false
return 0;
}