Polymorphism in C++

Last Updated : 31 Aug, 2026

The word polymorphism means having many forms. In C++, polymorphism concept can be applied to functions and operators. A single function name can work differently in different situations. Similarly, an operator works different when used in different context.

  • Same function or operator can behave differently depending on the context or object it is used with.
  • Achieved through function overloading and function overriding, improving code reusability and flexibility.
C++
#include <iostream>
using namespace std;

class Animal {
public:
    // Function to display animal sound
    void sound() {
        cout << "Animal makes a sound";
    }
};

class Dog : public Animal {
public:
    // Overriding the sound function
    void sound() {
        cout << "Dog barks";
    }
};

int main() {
    Dog d;

    // Calling the Dog class function
    d.sound();

    return 0;
}

Output
Dog barks

Explanation: The Dog class provides its own implementation of the sound() function. When d.sound() is called, the Dog class version is executed, showing how the same function name can have different behavior in different classes.

Types of Polymorphism

In C++, polymorphism is mainly divided into two types

Poly
Types of Polymorphism

Compile-Time Polymorphism

Compile-time polymorphism is also known as static polymorphism or early binding. In this type of polymorphism, the compiler decides which function or operator to call during compilation. It is achieved using:

1. Function Overloading

Function Overloading allows multiple functions to have the same name but different parameter lists.

  • Functions differ by the number or type of parameters.
  • The compiler selects the appropriate function during compilation.
  • Improves code readability by using a common function name.
C++
#include <bits/stdc++.h>
using namespace std;

class Geeks {
public:
    
    // Function to add two integers
    void add(int a, int b) {
        cout << "Integer Sum = " << a + b
        << endl;
    }
    
    // Function to add two floating point values
    void add(double a, double b) {
        cout << "Float Sum = " << a + b
        << endl ;
    }
};

int main() {
    Geeks gfg;
    
    // add() called with int values
    gfg.add(10, 2);

    // add() called with double value
    gfg.add(5.3, 6.2);

    return 0;
}

Output
Integer Sum = 12
Float Sum = 11.5

Explanation: The class contains two add() functions with different parameter types. The compiler selects the appropriate function based on the arguments passed during the function call.

2. Operator Overloading

Operator overloading allows operators such as +, -, and * to work with user-defined types.

  • Gives custom meaning to existing operators.
  • Makes user-defined objects easier to use.
  • Improves code readability.

Note: Operators such as ::, ., .*, ?:, and sizeof cannot be overloaded because they are essential to the core functionality of the language.

CPP
#include <iostream>
using namespace std;

class Complex {
public:
    int real, imag;
    
    Complex(int r, int i) :
    real(r), imag(i) {}

    // Overloading the '+' operator
    Complex operator+(const Complex& obj) {
        return Complex(real + obj.real, imag + obj.imag);
    }
};

int main() {
    Complex c1(10, 5), c2(2, 4);
    
    // Adding c1 and c2 using + operator
    Complex c3 = c1 + c2;  
    cout << c3.real << " + i" << c3.imag;
    return 0;
}

Output
12 + i9

Explanation: The overloaded + operator adds the real and imaginary parts of two Complex objects. When c1 + c2 is used, the overloaded operator function is called automatically.

Runtime Polymorphism

Runtime polymorphism is also known as dynamic polymorphism or late binding. The decision about which function to execute is made while the program is running.

  • Achieved using virtual functions.
  • Implemented through function overriding.
  • Allows base class pointers or references to invoke derived class functions.

Real-Life Example:

Different animals represent polymorphism, where the same method speak() produces different outputs such as Bark, Meow, and Moo depending on the object calling the method.

Polymorphysm
Polymorphism

In above Diagram:

  • A Dog object says Bark
  • A Cat object says Meow
  • A Cow object says Moo

Even though all animals use the same function name speak(), the behavior changes according to the object.

1. Function Overriding

Function Overriding occurs when a derived class provides its own implementation of a virtual function defined in the base class.

  • Base class function must be declared as virtual.
  • Derived class provides its own implementation.
  • Function call is resolved at runtime.
C++
#include <bits/stdc++.h>
using namespace std;

class Base {
public:

    // Virtual function
    virtual void display() {
        cout << "Base class function";
    }
};

class Derived : public Base {
public:

    // Overriding the base class function
    void display() override {
        cout << "Derived class function";
    }
};

int main() {
    
    // Creating a pointer of type Base
    Base* basePtr;
    
    // Creating an object of Derived class
    Derived derivedObj;

    // Pointing base class pointer to 
    // derived class object
    basePtr = &derivedObj;
    
    // Calling the display function 
    // using base class pointer
    basePtr->display();
    return 0;
}

Output
Derived class function

Explanation

  • A virtual function display() is defined in the base class and is overridden in the derived class.
  • A base class pointer is used to point to a derived class object.
  • When display() is called using the base pointer, the derived class version is executed at runtime due to dynamic binding.

Advantages of Polymorphism

Polymorphism makes C++ programs more flexible and easier to maintain.

  • Promotes code reusability by using a common interface.
  • Simplifies program design by reducing duplicate code.
  • Makes applications easier to extend with new classes.
  • Improves maintainability through loose coupling.
  • Enables dynamic behavior using inheritance and virtual functions.

Compile-Time Vs Runtime Polymorphism

The major difference between the compile-time and runtime polymorphism is:

Compile Time Polymorphism

Run time Polymorphism

Also called static binding

Also called dynamic binding

Achieved using function overloading and operator overloading

Achieved using virtual functions and function overriding

Decision made by the compiler at compile time

Decision made at runtime using vtables

Faster due to early binding

More flexible but slightly slower

Comment