← Back to C++ Course | Chapter 10: Polymorphism & Abstraction | Lesson 1 of 11

C++ Polymorphism Introduction

What is Polymorphism?

Polymorphism, literally 'many forms', lets a single action be carried out differently depending on the actual type of the object it's performed on, so the same function call can produce different behavior for different kinds of objects without the caller needing to know which kind it has.

Example: What is Polymorphism?

cpp
#include <iostream>

class Animal {
public:
	virtual void speak() { std::cout << "..." << std::endl; }
};

class Dog : public Animal {
public:
	void speak() override { std::cout << "Woof" << std::endl; }
};

int main() {
	Animal *a = new Dog();
	a->speak();
	delete a;
	return 0;
}

Types of Polymorphism

C++ supports both static (compile-time) polymorphism, achieved through function and operator overloading, and dynamic (runtime) polymorphism, achieved through virtual functions — the two differ in when the decision about which function to call actually gets made.

Example: Types of Polymorphism

cpp
#include <iostream>

void show(int x) { std::cout << "int: " << x << std::endl; }
void show(double x) { std::cout << "double: " << x << std::endl; }

class Animal {
public:
	virtual void speak() { std::cout << "Animal" << std::endl; }
};

int main() {
	show(5);
	show(5.5);
	Animal a;
	a.speak();
	return 0;
}

Compile-Time Polymorphism

Compile-time polymorphism is resolved entirely by the compiler before the program ever runs, based purely on function names and argument types, which makes it essentially free at runtime since there's no decision left to make while the program executes.

Example: Compile-Time Polymorphism

cpp
#include <iostream>

int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }

int main() {
	std::cout << add(2, 3) << std::endl;
	std::cout << add(2.5, 3.5) << std::endl;
	return 0;
}

Runtime Polymorphism Concept

Runtime polymorphism lets you write code against a parent pointer or reference while the actual method that executes is determined dynamically, based on the real (derived) type of the object the pointer happens to be pointing at when the call occurs.

Example: Runtime Polymorphism Concept

cpp
#include <iostream>

class Shape {
public:
	virtual void draw() { std::cout << "Shape" << std::endl; }
};

class Circle : public Shape {
public:
	void draw() override { std::cout << "Circle" << std::endl; }
};

int main() {
	Shape *s = new Circle();
	s->draw();
	delete s;
	return 0;
}

Benefits of Polymorphism

Polymorphism is what makes object-oriented code extensible: you can add entirely new derived classes later without touching a single line of the existing code that already works through base class pointers, since that code never needed to know about specific subtypes in the first place.

Example: Benefits of Polymorphism

cpp
#include <iostream>

class Shape {
public:
	virtual void draw() { std::cout << "Shape" << std::endl; }
};

class Triangle : public Shape {
public:
	void draw() override { std::cout << "Triangle" << std::endl; }
};

void render(Shape *s) { s->draw(); }

int main() {
	Shape *t = new Triangle();
	render(t);
	delete t;
	return 0;
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.