C++

Polymorphism in C++

Polymorphism is a Greek word that translates to "many forms." In C++, it is the ability of a message (a function call or operator) to be processed in more than one way. It allows a single interface to represent a general class of actions, with the specific action being determined by the exact nature of the situation.

1. The Theory: Static vs. Dynamic Binding

Theoretically, polymorphism is divided into two main categories based on when the decision of which function to call is made.

A. Compile-Time Polymorphism (Static Binding)

The compiler determines which function to call at the time of compilation. This is fast and efficient.

  • Function Overloading: Multiple functions with the same name but different parameters.

  • Operator Overloading: Giving special meaning to operators (like + or <<) for user-defined classes.

B. Runtime Polymorphism (Dynamic Binding)

The decision of which function to call is delayed until the program is actually running. This is achieved through Inheritance and Virtual Functions.

  • Method Overriding: A derived class provides a specific implementation of a function already defined in its base class.

2. Compile-Time Polymorphism

Function Overloading

You can have multiple functions with the same name as long as their "signatures" (number or types of arguments) are different.

Theory: The compiler performs "Name Mangling," creating unique internal names for each version of the function to keep them distinct.

Operator Overloading

This allows you to redefine how operators work with objects. For example, you can use the + operator to add two ComplexNumber objects together.

3. Runtime Polymorphism (The Core of OOP)

This is the most "powerful" form of polymorphism. It allows a Base Class Pointer to point to a Derived Class Object and call the correct version of a function.

The virtual Keyword

To enable runtime polymorphism, you must declare the base class function as virtual.

  • Theory: Without virtual, C++ performs "Early Binding," calling the function associated with the pointer type.

  • With virtual, C++ performs "Late Binding," calling the function associated with the actual object the pointer is holding.

4. Long Theory: The VTable and VPtr

How does the computer know which function to call at runtime? C++ uses a hidden mechanism called the Virtual Table (VTable).

  1. The VTable: For every class that contains at least one virtual function, the compiler creates a static table. This table contains the memory addresses of all the virtual functions for that specific class.

  2. The VPtr (Virtual Pointer): Every object created from such a class contains a hidden pointer (vptr). This pointer points to the VTable of its class.

  3. The Call: When you call a virtual function through a pointer, the program follows these steps:

    • Follow the object's vptr to the VTable.

    • Look up the address of the function in the VTable.

    • Jump to that address and execute the code.

Theoretical Cost: Runtime polymorphism has a tiny overhead because of this extra "look-up" step, but it provides immense flexibility.

5. Practical Code Example

#include <iostream>
using namespace std;

// Base Class
class Shape {
public:
    // Virtual function: enables runtime polymorphism
    virtual void draw() {
        cout << "Drawing a generic shape..." << endl;
    }
    
    // Virtual destructor is vital when using polymorphism!
    virtual ~Shape() {} 
};

class Circle : public Shape {
public:
    void draw() override { // 'override' is optional but best practice
        cout << "Drawing a Circle!" << endl;
    }
};

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

int main() {
    // A base class pointer can point to any derived object
    Shape* s;
    
    Circle c;
    Square sq;

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

    s = &sq;
    s->draw(); // Calls Square's draw()

    return 0;
}

6. Pure Virtual Functions and Abstract Classes (Long Theory)

Sometimes, a base class is so general that it shouldn't have a definition for a function. For example, what does it mean to "draw" a generic Shape?

  • Pure Virtual Function: A function declared with = 0.

    • virtual void draw() = 0;

  • Abstract Class: Any class containing at least one pure virtual function. You cannot create an object of an abstract class. It exists only to act as a blueprint for other classes.

  • Theory: This forces all derived classes to implement the function, ensuring a consistent interface across your entire program.

Upcoming Course
Upcoming Course
Learn More
Instructor Tips
Instructor Tips
View Tips
Join Community
Join Community
Join Now