Polymorphism
Polymorphism
Polymorphism is one of the core concepts of Object-Oriented Programming (OOP), and in C++,
it allows objects of different classes to be treated as objects of a common base class. This
concept enables functions or methods to process objects differently depending on their data type
or class. Polymorphism in C++ is primarily achieved through two types: compile-time (or
static) polymorphism and run-time (or dynamic) polymorphism. Polymorphism in C++ is a
powerful feature that enables code reusability and flexibility. By allowing different classes to
define their behaviors while sharing a common interface, it supports scalable and maintainable
code. Understanding and effectively using both compile-time and run-time polymorphism is
essential for mastering C++ programming in an object-oriented environment.
1. Compile-Time Polymorphism
a. Function Overloading
Function overloading allows you to have multiple functions with the same name but different
parameter lists (either in number or type). The correct function to invoke is determined at
compile-time based on the arguments provided.
#include <iostream>
using namespace std;
class Example {
public:
void display(int i) {
cout << "Integer: " << i << endl;
}
void display(double d) {
cout << "Double: " << d << endl;
}
void display(string s) {
cout << "String: " << s << endl;
}
};
int main() {
Example ex;
ex.display(5);
ex.display(3.14);
ex.display("Hello, world!");
return 0;
}
Output:
Integer: 5
Double: 3.14
String: Hello, world!
2. Run-Time Polymorphism
Run-time polymorphism is achieved using inheritance and virtual functions. It allows functions
to be called dynamically at runtime. The decision about which function to invoke is made during
program execution.
To achieve run-time polymorphism, C++ uses a feature called virtual functions. A virtual
function is defined in the base class and is meant to be overridden in derived classes. When a
base class pointer or reference is used to point to a derived class object, the derived class's
version of the function is called.
#include <iostream>
using namespace std;
class Base {
public:
void print() {
cout << "Base class print() function" << endl;
}
};
class Derived : public Base {
public:
void show() override { // Function overriding
cout << "Derived class show() function" << endl;
}
int main() {
Base *basePtr;
Derived derivedObj;
basePtr = &derivedObj;
// Run-time polymorphism
basePtr->show(); // Calls Derived class show()
basePtr->print(); // Calls Base class print() (no polymorphism here)
return 0;
}
Output:
Key Points:
Virtual Function: Declared in the base class using the keyword virtual, it ensures that
the function is overridden in the derived class.
Override Specifier: The override keyword is used in the derived class to indicate that the
function is overriding a base class's virtual function.
Base Class Pointer: When a base class pointer points to a derived class object, the
derived class's version of the virtual function is invoked, enabling run-time
polymorphism.
Function Hiding: Non-virtual functions in the base class are hidden if redefined in the
derived class, but they do not participate in run-time polymorphism.
In some cases, you might want to create a function that must be overridden in any derived class.
This can be done using a pure virtual function, which makes the base class an abstract class.
An abstract class cannot be instantiated on its own and serves as a template for derived classes.
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() = 0; // Pure virtual function
};
int main() {
Shape *shape;
Circle circle;
Rectangle rectangle;
shape = &circle;
shape->draw();
shape = &rectangle;
shape->draw();
return 0;
}
Output:
Drawing Circle
Drawing Rectangle