GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • C++ Tutorial
  • Interview Questions
  • Examples
  • Quizzes
  • Projects
  • Cheatsheet
  • OOP
  • Exception Handling
  • STL
  • DSA C++
  • friend functions
  • Introduction2 min read
  • Data Types4 min read
  • Variables4 min read

This view

  • Original page
  • New address

GeezerVison is showing www.geeksforgeeks.org — Virtual Function in C++ - GeeksforGeeks

geeksforgeeks
search icon
  • Courses
  • Tutorials
  • Interview Prep
  • C++ Tutorial
  • Interview Questions
  • Examples
  • Quizzes
  • Projects
  • Cheatsheet
  • OOP
  • Exception Handling
  • STL
  • DSA C++

Virtual Function in C++

Last Updated : 2 Sep, 2026

A virtual function is a member function declared with the virtual keyword in a base class and overridden in a derived class. It enables runtime polymorphism by allowing the appropriate function to be selected based on the actual object type.

  • Enables dynamic function dispatch through base class pointers and references.
  • Allows derived classes to provide their own implementation of inherited functions.
  • Forms the foundation of runtime polymorphism in C++.
C++
#include <iostream>
using namespace std;

class Animal{
    
public:
    // Virtual function
    virtual void sound() {
        cout << "Animal makes a sound" << endl;
    }
};

class Dog : public Animal{
    
public:

    // Override the virtual function
    void sound() override {
        cout << "Dog barks" << endl;
    }
};

int main(){
    
    // Base class pointer pointing to derived class object
    Animal* a = new Dog();

    // Calls Dog's sound() due to virtual function
    a->sound();

    delete a; // Free allocated memory
    return 0;
}

Output
Dog barks

Explanation:

  • virtual function: The sound() function in the Animal class is declared as virtual.
  • Function overriding: The Dog class provides its own version of the sound() function.
  • Base class pointer: The Animal* pointer points to a Dog object.
  • Runtime polymorphism: a->sound() calls the Dog class's function at runtime.

Note: Using the override specifier is recommended because the compiler can detect if the derived function does not correctly override a base class virtual function.

Pure Virtual Function

A pure virtual function is declared by assigning = 0 to a virtual function. It makes the class abstract and requires derived classes to provide an implementation.

  • A class containing at least one pure virtual function is an abstract class and cannot be instantiated.
  • A derived class must override all inherited pure virtual functions to become a concrete class.
  • A pure virtual destructor must still have a definition if it is declared in the base class.
C++
#include <iostream>
using namespace std;

class Base
{
  public:
  
    // Pure virtual function
    virtual void display() = 0;

    // Pure virtual destructor
    virtual ~Base() = 0;
};

// Definition of pure virtual destructor
Base::~Base()
{
    cout << "Base destructor called" << endl;
}

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

    ~Derived()
    {
        cout << "Derived destructor called" << endl;
    }
};

int main()
{
    Base *basePtr;
    Derived derivedObj;
    basePtr = &derivedObj;
    basePtr->display();
    return 0;
}

Output
Derived class display

Explanation

  • display() is a pure virtual function, making Base an abstract class.
  • Derived overrides the display() function.
  • The pure virtual destructor is defined separately and ensures proper cleanup.
  • Calling display() through a base class pointer invokes the derived class implementation.

Early Binding and Late Binding

Binding is the process of associating a function call with the function definition that will be executed. In C++, binding can occur at either compile time or runtime.

  • Early Binding (Static Binding): The function call is resolved during compilation. Non-virtual functions use early binding, making function calls faster.
  • Late Binding (Dynamic Binding): The function call is resolved at runtime based on the actual object type. Virtual functions use late binding to enable runtime polymorphism.
C++
#include <iostream>
using namespace std;

class Animal{
public:

    // Virtual function
    virtual void sound() {
        cout << "Animal sound" << endl;
    }
};

class Dog : public Animal {
public:

    // Override parent function
    void sound() override {
        cout << "Dog barks" << endl;
    }
};

int main(){
    
    // Base class pointer
    Animal* a = new Dog();

    // Calls Dog's sound() function
    a->sound();

    // Free memory
    delete a; 
}

Output
print derived class
show base class

Explanation

  • print() is a virtual function, so the call is resolved at runtime and executes derived::print().
  • show() is a non-virtual function, so the call is resolved at compile time and executes base::show().
  • This demonstrates the difference between late binding and early binding.

Runtime Resolution Using vtable and vptr

Virtual functions achieve runtime polymorphism through two compiler-generated mechanisms: vtable and vptr.

actual_object
  • vtable (Virtual Table): A table maintained for each class that stores the addresses of its virtual functions.
  • vptr (Virtual Pointer): A hidden pointer stored in each object that points to the corresponding class's vtable.
  • In the diagram, each object contains its own vptr, which points to the appropriate vtable.
  • When a virtual function is called through a base class pointer or reference, the compiler follows the object's vptr to locate the correct function address in the vtable.
  • This ensures that the function belonging to the actual object type (such as Manager or Engineer) is executed at runtime.

Rules for Virtual Functions

Virtual functions follow these important rules:

  • Virtual functions are defined in the base class and can be overridden in derived classes (not mandatory; base version is used if not overridden).
  • They must have the same prototype in base and derived classes.
  • They are used through a base class pointer or reference to achieve runtime polymorphism.
  • A class may have a virtual destructor in case of dynamic memory allocation, but never a virtual constructor.
  • Virtual functions cannot be static, but they can be friend functions of another class.

Limitations of Virtual Functions

While virtual functions enable runtime polymorphism, they also have some drawbacks:

  • Slight Performance Overhead: Virtual function calls are resolved at runtime, making them slightly slower than normal function calls.
  • Additional Memory Usage: Classes with virtual functions require a hidden vptr for runtime dispatch.
  • Harder to Debug: In complex programs, it can be more difficult to determine which function implementation is actually being executed.
Comment

Explore

    C++ Basics
    • Introduction2 min read
    • Data Types4 min read
    • Variables4 min read
    • Operators9 min read
    • Basic Input / Output2 min read
    • Control Flow Statements15+ min read
    • Loops7 min read
    • Functions5 min read
    • Arrays5 min read
    Core Concepts
    • Pointers and References4 min read
    • new and delete Operators5 min read
    • Templates in C++7 min read
    • Struct Union Enum3 min read
    • Exception Handling5 min read
    • File Handling9 min read
    • Multithreading6 min read
    • Namespace5 min read
    OOP
    • OOP Concepts10 min read
    • Inheritance6 min read
    • Polymorphism5 min read
    • Encapsulation3 min read
    • Abstraction4 min read
    Standard Template Library(STL)
    • STL3 min read
    • Container Library3 min read
    • Iterators10 min read
    • Algorithm Library3 min read
    Practice & Problems
    • Interview Questions15+ min read
    • Programming Examples4 min read
    Courses
    • Placement 360 Course2 min read
    • DSA and System Design Course2 min read
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.