Virtual Function in C++



A virtual function in C++ is a member function in a base class, which is further overridden in derived classes. This helps in enabling runtime polymorphism, which means the function to be executed is determined at runtime, not compile-time as the function that gets called depends on the actual object type, not the pointer or reference type.

Virtual Function Declaration

A virtual function is declared in the base class using the virtual keyword.

Syntax

Below is the syntax of virtual function declaration:

class BaseClassName { public: virtual void func_name() { // implementation } };

Where,

  • BaseClassName is the name of a base class given by a user.
  • func_name is the name of a function given.

How Virtual Functions Work

In C++, Virtual Functions allow runtime polymorphism, which means the function, that gets called depends on the actual object type, not the pointer or reference type, and this is done by using a mechanism called the vtable (virtual table) and vptr (virtual table pointer).

Virtual Table (VTable) and Virtual Pointer (VPTR)

Virtual Table is a table of function pointers, which is created for each class that has virtual functions, it stores addresses of virtual functions of the class.
Whereas each object of that class with virtual functions contains a hidden vptr, where this vptr points to the vtable of its class.

Step-by-Step Working

  1. When we declare a function as virtual in the base class, it enables dynamic binding instead of static binding.
  2. For a class with virtual functions, the compiler creates a vtable, which stores pointers to those functions.
  3. Here each object of a class with virtual functions has a vptr, which points to the class's vtable.
  4. Then a base class pointer uses vptr to fetch the correct function from the vtable at runtime, ensuring the derived class's overridden function is called.

Example

#include<iostream> using namespace std; class shape { public: virtual void draw() { // Virtual function cout << "Creating a shape!" << endl; } }; class circle: public shape { public: void draw() { // Overriding virtual function cout << "Creating a Circle!" << endl; } }; class square: public shape { public: void draw() { // Overriding virtual function cout << "Creating a Square!" << endl; } }; int main() { shape * shapePtr; // Base class pointer circle c; square s; shapePtr = & c; // Pointing to circle object shapePtr -> draw(); // Calls circle's draw() method shapePtr = & s; // Pointing to square object shapePtr -> draw(); // Calls square's draw() method return 0; }

Output

Creating a Circle!
Creating a Square!

Explanation

  1. Firstly, a base class named shape is created with virtual function draw(), therefor it will set up the mechanism of VTable for this class.
  2. Now the circle class inherits from shape and overrides draw(), so when a circle object is used, then its draw() function is called.
  3. Similar to the circle, the square class will also override the draw() function.
  4. Now, in int main(), shape* shapePtr; is a pointer of type shape, which will point to objects of circle or square.
  5. shapePtr = &c; this base class pointer points to the circle object c and shapePtr->draw(); calls circle's draw() function.
  6. Similarly, shapePtr = &s; this base class pointer points to the square object s and shapePtr->draw(); calls square's draw() function.

Rules for Virtual Functions

  1. Virtual function must be declared in the base class using the "virtual" keyword. If virtual is omitted, overriding will not work dynamically.
  2. Virtual functions must be accessed through a base class pointer or reference. If it is accessed directly using an object then compile-time binding will occur.
  3. With a virtual function, a base class must also have a virtual destructor to prevent memory leaks. In case the destructor is not virtual then only the base class destructor will be called, causing a memory leak.
  4. A Class with a pure virtual function becomes an abstract class and cannot be instantiated and If a derived class does not override a pure virtual function, It also becomes abstract.
    class Base { public: virtual void show() = 0; // Pure virtual function };
  5. Virtual can be both public and private where public can be accessed using an object or pointer but private cannot be accessed directly but it can still be inherited and overridden in the derived class.
  6. Constructors, Static, and Friend Functions cannot be virtual.
Advertisements
close