
- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Hello World
- C++ Omitting Namespace
- C++ Tokens
- C++ Constants/Literals
- C++ Keywords
- C++ Identifiers
- C++ Data Types
- C++ Numeric Data Types
- C++ Character Data Type
- C++ Boolean Data Type
- C++ Variable Types
- C++ Variable Scope
- C++ Multiple Variables
- C++ Basic Input/Output
- C++ Modifier Types
- C++ Storage Classes
- C++ Numbers
- C++ Enumeration
- C++ Enum Class
- C++ References
- C++ Date & Time
- C++ Operators
- C++ Arithmetic Operators
- C++ Relational Operators
- C++ Logical Operators
- C++ Bitwise Operators
- C++ Assignment Operators
- C++ sizeof Operator
- C++ Conditional Operator
- C++ Comma Operator
- C++ Member Operators
- C++ Casting Operators
- C++ Pointer Operators
- C++ Operators Precedence
- C++ Unary Operators
- C++ Control Statements
- C++ Decision Making
- C++ if Statement
- C++ if else Statement
- C++ Nested if Statements
- C++ switch Statement
- C++ Nested switch Statements
- C++ Loop Types
- C++ while Loop
- C++ for Loop
- C++ do while Loop
- C++ Foreach Loop
- C++ Nested Loops
- C++ break Statement
- C++ continue Statement
- C++ goto Statement
- C++ Strings
- C++ Strings
- C++ Loop Through a String
- C++ String Length
- C++ String Concatenation
- C++ String Comparison
- C++ Functions
- C++ Functions
- C++ Multiple Function Parameters
- C++ Recursive Function
- C++ Return Values
- C++ Function Overloading
- C++ Function Overriding
- C++ Default Arguments
- C++ Arrays
- C++ Arrays
- C++ Multidimensional Arrays
- C++ Pointer to an Array
- C++ Passing Arrays to Functions
- C++ Return Array from Functions
- C++ Structure & Union
- C++ Structures
- C++ Unions
- C++ Pointers
- C++ Pointers
- C++ Dereferencing
- C++ Modify Pointers
- C++ Class and Objects
- C++ Object Oriented
- C++ Classes & Objects
- C++ Class Member Functions
- C++ Class Access Modifiers
- C++ Static Class Members
- C++ Static Data Members
- C++ Static Member Function
- C++ Inline Functions
- C++ this Pointer
- C++ Friend Functions
- C++ Pointer to Classes
- C++ Constructors
- C++ Constructor & Destructor
- C++ Default Constructors
- C++ Parameterized Constructors
- C++ Copy Constructor
- C++ Constructor Overloading
- C++ Constructor with Default Arguments
- C++ Delegating Constructors
- C++ Constructor Initialization List
- C++ Dynamic Initialization Using Constructors
- C++ Object-oriented
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
- C++ Virtual Function
- C++ Pure Virtual Functions & Abstract Classes
- C++ File Handling
- C++ Files and Streams
- C++ Reading From File
- C++ Advanced
- C++ Exception Handling
- C++ Dynamic Memory
- C++ Namespaces
- C++ Templates
- C++ Preprocessor
- C++ Signal Handling
- C++ Multithreading
- C++ Web Programming
- C++ Socket Programming
- C++ Concurrency
- C++ Advanced Concepts
- C++ Lambda Expression
- C++ unordered_multiset
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
- When we declare a function as virtual in the base class, it enables dynamic binding instead of static binding.
- For a class with virtual functions, the compiler creates a vtable, which stores pointers to those functions.
- Here each object of a class with virtual functions has a vptr, which points to the class's vtable.
- 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
- Firstly, a base class named shape is created with virtual function draw(), therefor it will set up the mechanism of VTable for this class.
- Now the circle class inherits from shape and overrides draw(), so when a circle object is used, then its draw() function is called.
- Similar to the circle, the square class will also override the draw() function.
- Now, in int main(), shape* shapePtr; is a pointer of type shape, which will point to objects of circle or square.
- shapePtr = &c; this base class pointer points to the circle object c and shapePtr->draw(); calls circle's draw() function.
- 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
- Virtual function must be declared in the base class using the "virtual" keyword. If virtual is omitted, overriding will not work dynamically.
- 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.
- 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.
- 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 };
- 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.
- Constructors, Static, and Friend Functions cannot be virtual.