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>usingnamespacestd;classAnimal{public:// Virtual functionvirtualvoidsound(){cout<<"Animal makes a sound"<<endl;}};classDog:publicAnimal{public:// Override the virtual functionvoidsound()override{cout<<"Dog barks"<<endl;}};intmain(){// Base class pointer pointing to derived class objectAnimal*a=newDog();// Calls Dog's sound() due to virtual functiona->sound();deletea;// Free allocated memoryreturn0;}
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>usingnamespacestd;classBase{public:// Pure virtual functionvirtualvoiddisplay()=0;// Pure virtual destructorvirtual~Base()=0;};// Definition of pure virtual destructorBase::~Base(){cout<<"Base destructor called"<<endl;}classDerived:publicBase{public:voiddisplay()override{cout<<"Derived class display"<<endl;}~Derived(){cout<<"Derived destructor called"<<endl;}};intmain(){Base*basePtr;DerivedderivedObj;basePtr=&derivedObj;basePtr->display();return0;}
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>usingnamespacestd;classAnimal{public:// Virtual functionvirtualvoidsound(){cout<<"Animal sound"<<endl;}};classDog:publicAnimal{public:// Override parent functionvoidsound()override{cout<<"Dog barks"<<endl;}};intmain(){// Base class pointerAnimal*a=newDog();// Calls Dog's sound() functiona->sound();// Free memorydeletea;}
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.
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.
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.