Skip to main content

A Practical Guide to C++ Virtual Functions and Polymorphism

·609 words·3 mins
C++ Virtual Function Polymorphism
Table of Contents

The virtual function is one of the core pillars of C++ object-oriented programming. It unlocks polymorphism, allowing different objects to respond to the same interface in different ways.


1. ๐Ÿ” What Are Virtual Functions?
#

A virtual function is a function in a base class that can be overridden in derived classes. When called through a base pointer or reference, the function invoked depends on the actual object typeโ€”not the pointer type.

Example:

#include <iostream>
using namespace std;

class Shape {
public:
    virtual void draw() {
        cout << "Drawing a shape" << endl;
    }
};

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

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

int main() {
    Circle circle;
    Square square;

    Shape* shape1 = &circle;
    Shape* shape2 = &square;

    shape1->draw();  // Drawing a circle
    shape2->draw();  // Drawing a square
}

Even though shape1 and shape2 are Shape*, C++ dispatches the correct function at runtime.


2. ๐Ÿ“ Key Characteristics of Virtual Functions
#

2.1 Runtime (Dynamic) Binding
#

Virtual functions support dynamic binding, meaning:

  • The function call is resolved at runtime
  • Behavior depends on the actual object type

This gives C++ strong polymorphic capabilities.

2.2 Virtual Table (vtable)
#

Under the hood, virtual functions are implemented using a vtable:

  • Each class with virtual functions has its own vtable.
  • Each object stores a hidden pointer (vptr) to its classโ€™s vtable.
  • Virtual calls use the vptr โ†’ vtable โ†’ correct function.

This design ensures fast and predictable dispatch.


3. ๐ŸŽฏ When to Use Virtual Functions
#

3.1 With Inheritance
#

Use virtual functions to express shared behavior at the base level but different implementations at the derived level.

class Animal {
public:
    virtual void makeSound() {
        cout << "Generic animal sound" << endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        cout << "Woof!" << endl;
    }
};

3.2 When Polymorphism Is Needed
#

Virtual functions are the mechanism that enables:

  • Plugin systems
  • Strategy patterns
  • Interfaces/abstract classes
  • Heterogeneous collections

4. ๐Ÿ› ๏ธ How to Use Virtual Functions
#

4.1 Declaring Virtual Functions
#

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

4.2 Pure Virtual Functions and Abstract Classes
#

A pure virtual function forces derived classes to implement it:

class AbstractBase {
public:
    virtual void run() = 0;  // Pure virtual โ†’ abstract class
};

Any class containing at least one pure virtual function becomes abstract and cannot be instantiated.


5. ๐Ÿง‘โ€๐Ÿ’ป Practical Example: Plugin System
#

A plugin architecture is a common real-world use case for polymorphism.

#include <iostream>
using namespace std;

class Plugin {
public:
    virtual void apply() {
        cout << "Applying a generic plugin" << endl;
    }
};

class FilterPlugin : public Plugin {
public:
    void apply() override {
        cout << "Applying a filter plugin" << endl;
    }
};

class DrawingPlugin : public Plugin {
public:
    void apply() override {
        cout << "Applying a drawing plugin" << endl;
    }
};

Using polymorphism:

int main() {
    FilterPlugin filter;
    DrawingPlugin drawing;

    Plugin* p1 = &filter;
    Plugin* p2 = &drawing;

    p1->apply();  // Applying a filter plugin
    p2->apply();  // Applying a drawing plugin
}

This allows new plugin types to be added easilyโ€”just subclass Plugin and override apply().


๐Ÿ“ Summary
#

Virtual functions are essential for writing modular, extensible, object-oriented C++:

  • They enable runtime polymorphism
  • Implemented through vtables
  • Support both normal and pure virtual functions
  • Widely used in plugin systems, frameworks, and architecture design

Mastering virtual functions is key to writing flexible, maintainable C++ code.

Related

C++ๅ†…ๅญ˜็ฎก็†็š„ๅฅฅ็ง˜
·242 words·2 mins
็จ‹ๅบ C++ Memory Management
NULL vs nullptr in Modern C++: What Developers Should Know
·537 words·3 mins
C C++ NULL Nullptr
Mastering C++ Exception Handling for Robust Code
·718 words·4 mins
C++ Exception Handling RAII