C++ Polymorphism

Polymorphism is one of the core concepts of object-oriented programming (OOP) in C++. It allows objects of different types to be treated as objects of a common base type, enabling a single function, method, or operator to operate on different types of objects. Polymorphism is achieved through method overriding (runtime polymorphism) and method overloading (compile-time polymorphism).


Types of Polymorphism

  1. Compile-Time Polymorphism: Also known as static polymorphism, this is achieved through function overloading and operator overloading.
  2. Runtime Polymorphism: Also known as dynamic polymorphism, this is achieved through inheritance and virtual functions.

Compile-Time Polymorphism

Example 1: Function Overloading

Function overloading allows multiple functions with the same name but different parameter lists to coexist.

</>
Copy
#include <iostream>
using namespace std;

class Calculator {
public:
    int add(int a, int b) {
        return a + b;
    }

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

int main() {
    Calculator calc;
    cout << "Integer addition: " << calc.add(5, 10) << endl;
    cout << "Double addition: " << calc.add(5.5, 10.5) << endl;
    return 0;
}

Output:

Integer addition: 15
Double addition: 16

Example 2: Operator Overloading

Operator overloading allows operators to be redefined for user-defined types.

</>
Copy
#include <iostream>
using namespace std;

class Complex {
public:
    double real, imag;

    Complex(double r, double i) : real(r), imag(i) {}

    Complex operator+(const Complex& other) {
        return Complex(real + other.real, imag + other.imag);
    }

    void display() {
        cout << real << " + " << imag << "i" << endl;
    }
};

int main() {
    Complex c1(1.5, 2.5), c2(3.0, 4.0);
    Complex c3 = c1 + c2;
    c3.display();
    return 0;
}

Output:

4.5 + 6.5i

Runtime Polymorphism

Example 1: Virtual Functions

Virtual functions enable dynamic dispatch, where the function to be called is determined at runtime.

</>
Copy
#include <iostream>
using namespace std;

class Base {
public:
    virtual void show() {
        cout << "Base class show" << endl;
    }
};

class Derived : public Base {
public:
    void show() override {
        cout << "Derived class show" << endl;
    }
};

int main() {
    Base* basePtr;
    Derived derivedObj;

    basePtr = &derivedObj;
    basePtr->show(); // Calls Derived class's show function

    return 0;
}

Output:

Derived class show

Example 2: Abstract Base Classes

An abstract base class with pure virtual functions provides a blueprint for derived classes.

</>
Copy
#include <iostream>
using namespace std;

class Shape {
public:
    virtual void draw() = 0; // Pure virtual function
};

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

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

int main() {
    Shape* shape;

    Circle circle;
    Rectangle rectangle;

    shape = &circle;
    shape->draw(); // Calls Circle's draw

    shape = &rectangle;
    shape->draw(); // Calls Rectangle's draw

    return 0;
}

Output:

Drawing Circle
Drawing Rectangle

Key Points about Polymorphism in C++

  1. Polymorphism allows functions or operators to work with objects of different types.
  2. Compile-time polymorphism is achieved using function overloading and operator overloading.
  3. Runtime polymorphism is achieved using inheritance and virtual functions.
  4. Abstract base classes with pure virtual functions enforce derived classes to provide specific implementations.
  5. Polymorphism is a fundamental concept in object-oriented programming that promotes code reusability and flexibility.