In this tutorial, you will learn about Virtual Functions in C++. You will understand their purpose, how to use them, and why they are important. This topic covers dynamic polymorphism and method overriding at runtime. You will also see real-world examples to make the concept clear.
Contents:
- What is a Virtual Function in C++?
- Why Do We Need Virtual Functions in C++?
- How to Declare a Virtual Function in C++?
- Example of Virtual Function in C++
- Rules for Virtual Functions in C++
- Virtual Function and V-Table Mechanism in C++
- Pure Virtual Functions and Abstract Classes in C++
- Advantages of Virtual Functions in C++
- Disadvantages of Virtual Functions in C++
- FAQs on Virtual Function in C++
What is a Virtual Function in C++?
A virtual function in C++ is a member function in a base class that can be overridden in a derived class. When a base class pointer points to a derived class object, the derived class’s version of the function is invoked, ensuring runtime polymorphism.
Why Do We Need Virtual Functions in C++?
- Ensures Correct Function Calls: Calls the right function from the derived class, even when using a base class pointer.
- Supports Runtime Polymorphism: Allows different behaviors at runtime based on the actual object type.
- Prevents Unexpected Behavior: Without virtual functions, the base class version might run instead of the derived class version.
- Makes Code Flexible: Enables easy modifications and extensions without changing existing code.
- Simplifies Maintenance: Helps keep the code clean and easier to manage over time.
How to Declare a Virtual Function in C++?
A base class uses the virtual keyword to declare a virtual function. A derived class overrides it by keeping the same function signature.
Syntax:
class Base { public: virtual void show() { // Virtual function cout << "Base class function" << endl; } };
Example of Virtual Function in C++
#include <iostream> using namespace std; // Base class - SanfoundryCourse class SanfoundryCourse { public: // Virtual function to display course info virtual void courseInfo() { cout << "Sanfoundry: General Course" << endl; } }; // Derived class - CppCourse class CppCourse : public SanfoundryCourse { public: // Overriding courseInfo() for C++ course void courseInfo() override { cout << "Sanfoundry: C++ Course" << endl; } }; int main() { SanfoundryCourse* coursePtr; CppCourse cpp; coursePtr = &cpp; coursePtr->courseInfo(); // Calls CppCourse version return 0; }
Output:
Sanfoundry: C++ Course
This C++ program shows runtime polymorphism using virtual functions. The base class SanfoundryCourse has a virtual function courseInfo(). The derived class CppCourse overrides this function. A base class pointer (coursePtr) points to a CppCourse object. When coursePtr->courseInfo(); runs, it calls the function from CppCourse, printing “Sanfoundry: C++ Course“. This ensures the right function runs at runtime.
Rules for Virtual Functions in C++
- A virtual function in a base class enables dynamic polymorphism, allowing derived classes to override it.
- If a derived class does not override a virtual function, the base class version runs instead.
- Virtual functions use runtime binding, meaning the function executed depends on the actual object type.
- A base class pointer or reference calling a virtual function runs the derived class version if overridden.
- C++ uses a VTable (Virtual Table) and vptr (virtual pointer) to manage virtual function calls efficiently.
- A pure virtual function (= 0) makes a class abstract, so you can’t create objects from it. You must inherit and override the function.
- A virtual destructor makes sure the right destructor runs when deleting a derived object through a base class pointer. This prevents memory leaks.
Virtual Function and V-Table Mechanism in C++
| Feature | Virtual Function | V-Table Mechanism |
|---|---|---|
| Definition | A member function in a base class that can be overridden in a derived class. | A table storing addresses of virtual functions for a class. |
| Purpose | Enables runtime polymorphism (late binding). | Supports dynamic function resolution. |
| Binding Type | Decides the function at runtime (late binding). | Uses function pointers to pick the right function. |
| How It Works | Calls the correct function based on the actual object type, even when using a base class pointer. | Each object has a vptr (virtual pointer) that points to the class’s VTable. |
| Creation | Declared using the virtual keyword in the base class. | The compiler automatically makes a VTable for classes with virtual functions. |
| Modification in Derived Class | Can be overridden in the derived class. | The vptr looks up the correct function in the VTable. |
| Lookup Process | The base class pointer finds the function at runtime. | The vptr accesses the correct function from the VTable. |
| Performance Impact | A little slower than normal functions due to extra lookup time. | Uses extra memory and processing to handle function calls. |
| Memory Overhead | Every object of a class with virtual functions has a vptr. | Every class with virtual functions has one VTable with function pointers. |
| Supports Abstract Classes? | Yes, using pure virtual functions (= 0). | Yes, as pure virtual functions leave a placeholder entry in the VTable. |
| Can it be Static? | No, virtual functions cannot be static. | No, VTable only handles functions for specific objects. |
| Can Constructors be Virtual? | No, but destructors should be virtual for proper cleanup. | No, constructors do not use VTable as they work with compile-time binding. |
Pure Virtual Functions and Abstract Classes in C++
What is a Pure Virtual Function in C++?
A pure virtual function is a virtual function that is declared in a base class but does not have any implementation in that class. It is specified by assigning = 0 to the virtual function.
Syntax:
virtual returnType functionName(parameters) = 0;
What is an Abstract Class in C++?
An abstract class is a class that contains at least one pure virtual function. You cannot instantiate an abstract class directly. It serves as a blueprint for derived classes that override the pure virtual function.
Example of Pure Virtual Function and Abstract Class:
#include <iostream> using namespace std; // Abstract class - SanfoundryCourse class SanfoundryCourse { public: // Pure virtual function virtual void courseInfo() = 0; // Regular function void showInfo() { cout << "Welcome to Sanfoundry Course Platform." << endl; } }; // Derived class - CppCourse class CppCourse : public SanfoundryCourse { public: void courseInfo() override { cout << "Sanfoundry C++ Course: Learn C++ from basics to advanced." << endl; } }; // Derived class - JavaCourse class JavaCourse : public SanfoundryCourse { public: void courseInfo() override { cout << "Sanfoundry Java Course: Learn Java step by step." << endl; } }; int main() { // Cannot create object of abstract class // SanfoundryCourse course; // Error! // Create objects of derived classes CppCourse cpp; JavaCourse java; // Accessing pure virtual function cpp.courseInfo(); java.courseInfo(); // Accessing regular function from base class cpp.showInfo(); java.showInfo(); return 0; }
Output:
Sanfoundry C++ Course: Learn C++ from basics to advanced. Sanfoundry Java Course: Learn Java step by step. Welcome to Sanfoundry Course Platform. Welcome to Sanfoundry Course Platform.
Explanation:
This C++ program shows how abstract classes and pure virtual functions work. The SanfoundryCourse class has a pure virtual function courseInfo(), which means it cannot be used directly. Instead, two classes, CppCourse and JavaCourse, override this function to give specific course details. The program creates objects of these classes and calls their versions of courseInfo(). It also shows how a regular function (showInfo()) from the base class can still be used. This helps in runtime polymorphism, making the code more flexible and reusable.
Advantages of Virtual Functions in C++
- Enables Runtime Polymorphism: Virtual functions allow function calls to be decided at runtime, making programs more flexible and adaptive.
- Promotes Code Reusability: A base class can provide a common function that derived classes can modify, reducing duplicate code.
- Ensures Correct Function Execution: Even if a base class pointer points to a derived object, the correct function is executed, preventing unexpected behavior.
- Simplifies Maintenance and Scaling: New classes can be added without changing existing code, making projects easier to update and expand.
- Supports Interfaces and OOP Principles: Virtual functions help create consistent interfaces and follow key OOP concepts like abstraction and polymorphism.
- Helps Implement Design Patterns: Patterns like Factory Method, Strategy, and Observer rely on virtual functions for flexible runtime behavior.
- Reduces Code Duplication: Base class functions can be reused with small changes in derived classes, making the code more efficient.
Disadvantages of Virtual Functions in C++
- Uses More Memory: Virtual functions need a V-Table (Virtual Table) and a V-Table Pointer (vptr) in each object. This takes up extra memory compared to regular functions.
- Slower Performance: Since virtual functions are decided at runtime, calling them takes longer than normal functions, making execution slightly slower.
- Cannot Be Inlined: Virtual functions cannot be inlined because their code is chosen at runtime. This prevents some speed improvements from compiler optimizations.
- More Complex Code: Programs with virtual functions can be harder to understand, especially if there are many levels of inheritance.
- Risk of Losing Data (Object Slicing): If you assign a base class object from a derived class without using pointers or references, the extra data from the derived class is lost.
- Harder to Debug: Since virtual functions run at runtime, finding errors related to incorrect function overriding can be tricky.
- Security Risks: Hackers can modify the V-Table in memory, tricking the program into running the wrong function. This is called function hijacking.
FAQs on Virtual Function in C++
1. What is a virtual function in C++?
A virtual function is a function in a base class that a derived class can override. It enables runtime polymorphism, meaning the program decides which function to call at runtime, not at compile-time.
2. Why do we need virtual functions in C++?
Virtual functions allow derived classes to override base class methods, making the code more flexible, reusable, and easier to maintain. They help achieve polymorphism in object-oriented programming.
3. What happens if a derived class does not override a virtual function?
If the derived class does not override a virtual function, the program calls the base class version when accessing it through a base class pointer or reference.
4. What are a V-Table and V-Ptr in virtual functions?
- V-Table (Virtual Table): A table that stores function pointers for a class’s virtual functions.
- V-Ptr (Virtual Pointer): A hidden pointer inside each object that points to the class’s V-Table. It helps the program resolve virtual function calls at runtime.
5. How do virtual functions differ from normal functions?
- Normal functions use static binding (decided at compile-time).
- Virtual functions use dynamic binding (decided at runtime).
- Virtual functions let derived classes override base class functions, even when accessed through a base class reference.
6. What is a pure virtual function?
A pure virtual function has no definition in the base class. The derived class must override it. A class with at least one pure virtual function becomes an abstract class, which means you cannot create objects from it.
Key Points to Remember
Here is the list of key points we need to remember about “Virtual Function in C++”.
- Virtual functions ensure that the correct function from a derived class is executed at runtime, even when accessed through a base class pointer.
- The virtual keyword in the base class allows derived classes to override functions, enabling runtime polymorphism.
- The V-Table stores function pointers for virtual functions, while the V-Ptr in each object helps in function lookup.
- A pure virtual function has no implementation in the base class, making it necessary for derived classes to override it. A class with at least one pure virtual function is abstract and cannot be instantiated.
- A virtual destructor ensures proper cleanup when deleting derived class objects through a base class pointer, preventing memory leaks.
- Virtual functions enhance code reusability, flexibility, and maintenance by allowing modifications without altering existing code structure.
- Using virtual functions increases memory usage due to the V-Table and V-Pointer, and they execute slightly slower than normal functions due to runtime resolution.
Continue learning C++ from basics to advanced topics in our complete C++ Tutorial.
Practice what you’ve learned with topic-wise questions on our C++ MCQs.