C++ supports polymorphism through two mechanisms: compile-time polymorphism (also known as static polymorphism) and runtime polymorphism (also known as dynamic polymorphism).
Compile-time polymorphism is achieved through function overloading and template specialization. Function overloading allows multiple functions with the same name but different parameter types to coexist in a program. Template specialization allows a single function template to generate different code depending on the types of the template parameters.
Runtime polymorphism is achieved through virtual functions and inheritance. Virtual functions allow a function to be overridden in a derived class, so that the behavior of the function can vary depending on the runtime type of the object. Inheritance allows a derived class to inherit the properties and methods of a base class, and to override or extend those properties and methods as needed.
Polymorphism is useful in object-oriented programming because it allows objects of different types to be treated in a uniform way, based on their common interface. This simplifies the code and makes it more modular and reusable. Polymorphism also allows for greater flexibility and extensibility, since new types can be added to the program without requiring changes to the existing code.
Hereβs an example of using runtime polymorphism to implement a simple drawing program:
#include <iostream>
#include <vector>
using namespace std;
class Shape {
public:
virtual void draw() const = 0;
};
class Rectangle : public Shape {
public:
void draw() const override {
cout << "Drawing rectangle" << endl;
}
};
class Circle : public Shape {
public:
void draw() const override {
cout << "Drawing circle" << endl;
}
};
int main() {
vector<Shape*> shapes;
shapes.push_back(new Rectangle());
shapes.push_back(new Circle());
for (auto shape : shapes) {
shape->draw();
}
for (auto shape : shapes) {
delete shape;
}
return 0;
}
In this example, we define a Shape class that serves as the base class for all shapes. We then define two derived classes, Rectangle and Circle, that override the draw function to implement their specific drawing behavior. We create a vector of Shape pointers, and add a Rectangle and a Circle object to it. We then iterate over the vector, calling the draw function on each object, which calls the appropriate draw function based on the runtime type of the object. Finally, we delete the dynamically allocated objects to release the memory.
By using runtime polymorphism, we can treat the Rectangle and Circle objects as Shapes, and call their draw function in a uniform way, even though they have different implementations. This makes the code more modular and extensible, and allows us to add new shapes to the program without requiring changes to the existing code.