Polymorphism in C++

Polymorphism means having many forms. In C++, Polymorphism means the ability of functions or objects to behave differently in different scenarios.

There are two types of polymorphism in C++:

  1. Compile-time Polymorphism
  2. Run-time Polymorphism

Compile-time Polymorphism

The Compile-time Polymorphism can be achieved by Function Overloading, or Operator Overloading.

  • Function Overloading - Function overloading is a compile-time polymorphism in which multiple functions have same names but different arguments. The arguments may be different in terms of number or type.
  • Example
    
    #include <iostream>
    using namespace std;
    
    class Product
    {
    public:
        double getDefaultPrice()
        {
            return 159.48;
        }
    
        double getDefaultPrice(double x)
        {
    
            return 159.48 + x;
        }
    
        double getDefaultPrice(double x, double y)
        {
    
            return 159.48 + x + y;
        }
    };
    
    int main(void)
    {
        //Creating Product class object
        Product productObject;
    
        //Invoking over-loading functions
        double defaultPrice1 = productObject.getDefaultPrice();
        double defaultPrice2 = productObject.getDefaultPrice(10);
        double defaultPrice3 = productObject.getDefaultPrice(12, 20);
    
        //Printing values
        cout <<  defaultPrice1 << endl;
        cout <<  defaultPrice2 << endl;
        cout <<  defaultPrice3 << endl;
        return 0;
    }    
    
    Output
    159.48
    169.48
    191.48
  • Operator Overloading - Operator Overloading is a compile-time polymorphism in which C++ operators are redefined without changing its actual meaning.
  • Example
    
    #include <iostream>
    using namespace std;
    
    class MyOperator
    {
    private:
        int num;
    
    public:
        MyOperator() : num(5) {}
    
        int operator++()
        {
            num = num + 10;
            return num;
        }
    };
    
    int main()
    {
        MyOperator myOperator;
        int result = ++myOperator; // calling operator++() function"
    
        cout << "Pre-increamenting value on myOperator: " << result;
    
        return 0;
    }
    
    Output
    Pre-increamenting value on myOperator: 15

Run-time Polymorphism

In Run-time Polymorphism, functions are called at the time of the program execution, therefore it is also called late binding or dynamic binding.

The Run-time polymorphism can be achieved by Function Overriding and Virtual function.

  • Function Overriding - Function overriding occurs when a derived/child class and base/parent class both contain a function having the same name.
  • Example
    
    #include <iostream>
    using namespace std;
    
    class Animal
    {
    public:
        void eat()
        {
            cout << "Animal eat " << endl;
        }
    };
    
    class Deer : public Animal
    {
    public:
        void eat()
        {
            cout << "Deer eat grass" << endl;
        }
    };
    
    class Tiger : public Animal
    {
    public:
        void eat()
        {
            cout << "Tiger eat meat" << endl;
        }
    };
    
    
    int main(void)
    {
    
        Deer deer = Deer();
        deer.eat();
    
        Tiger tiger = Tiger();
        tiger.eat();
    
        return 0;
    }
    
    Output
    Deer eat grass
    Tiger eat meat
  • Virtual Function - Virtual function is another way of implementing run-time polymorphism. A virtual function is a member function which is declared using a virtual keyword in the base class. A virtual functions is used to make sure that the correct function is called, regardless of the reference type used to call the function, the appropriate function is invoked for an object. They are mostly used to achieve runtime polymorphism.
  • Example
    
    #include <iostream>
    using namespace std;
    
    class BaseClass
    {
    public:
        virtual void show()
        {
            cout << "The show() function in base class is invoked" << endl;
        }
    };
    
    class ChildClass : public BaseClass
    {
    public:
        void show()
        {
            cout << "The show() function in derived class is invoked";
        }
    };
    
    
    int main()
    {
        BaseClass *a;
        ChildClass b;
        a = &b;
        a->show();
    }
    
    
    Output
    The show() function in derived class is invoked