Polymorphism in C++ is a programming technique that allows you to write code that can be used with different types of objects. This is done by using the same function name to perform different tasks, depending on the type of object that the function is called on.
Polymorphism is a key feature of object-oriented programming, and it allows you to write more flexible and reusable code.
There are two types of polymorphism in C++:
Compile-time polymorphism
Compile-time polymorphism allows you to write multiple functions with the same name, but with different parameter lists. The compiler will choose the appropriate function to call based on the data types of the arguments that you pass to the function.
For example, the following code shows two overloaded functions named add():
int add(int x, int y) {
return x + y;
}
double add(double x, double y) {
return x + y;
}
When you call the add() function, the compiler will choose the appropriate function to call based on the data types of the arguments that you pass to the function. For example:
int sum_int = add(10, 20); // Calls the first function
double sum_double = add(1.0, 2.0); // Calls the second function
Operator overloading is another example of compile-time polymorphism. Operator overloading allows you to define custom behaviors for operators such as +, -, and *. For example, the following code shows how to overload the + operator to add two vectors:
class Vector {
public:
Vector(int x, int y) : x(x), y(y) {}
Vector& operator+(const Vector& other) {
x += other.x;
y += other.y;
return *this;
}
private:
int x, y;
};
Now, you can add two vectors using the + operator:
Vector v1(1, 2);
Vector v2(3, 4);
Vector v3 = v1 + v2;
The compiler will call the custom + operator that you defined for the Vector class.
Run-time polymorphism
Run-time polymorphism allows you to write code that can be used with different types of objects, even if the types of objects are not known at compile time. This is done by using inheritance and virtual functions.
Virtual functions are functions that can be overridden in derived classes. When a virtual function is called, the compiler will determine which function to call based on the dynamic type of the object that the function is called on.
For example, the following code shows a base class named Animal with a virtual function named Speak():
class Animal {
public:
virtual void Speak() = 0;
};
The Speak() function is a pure virtual function, which means that it must be overridden in all derived classes.
The following code shows two derived classes, Dog and Cat, that override the Speak() function:
class Dog : public Animal {
public:
void Speak() override {
std::cout << "Woof!" << std::endl;
}
};
class Cat : public Animal {
public:
void Speak() override {
std::cout << "Meow!" << std::endl;
}
};
Now, you can create an array of Animal objects and call the Speak() function on each object:
Animal* animals[] = {new Dog(), new Cat()};
for (int i = 0; i < sizeof(animals) / sizeof(animals[0]); i++) {
animals[i]->Speak();
}
At run time, the compiler will determine which Speak() function to call based on the dynamic type of the object that the function is called on.