• Articles
  • Tutorials
  • Interview Questions

Virtual Function in C++

In this blog, we will be learning all about virtual functions in C++. We will discuss what they are, their rules, how to use them, and the differences between compile-time and runtime behaviors of virtual functions. Additionally, we will also be learning pure virtual functions, providing an overview of their role in C++ programming.

Table of Contents

Check out our YouTube video on C programming language for the absolute beginners:

Video Thumbnail

What is a Virtual Function in C++?

In C++, a virtual function is a member function within a base class that’s designed to be overridden in its derived classes. It allows a specific function to be reimplemented in the derived class while preserving a common interface across all derived classes. This concept is required for implementing runtime polymorphism.

When a function is declared “virtual” in a base class, it enables late binding or dynamic binding that ensures the correct overridden function in the derived class is invoked during runtime. This feature executes the function of the derived class when a pointer or reference to the base class type is used. Virtual functions make code more flexible by using a dynamic method of resolution that provides efficient utilization of polymorphism in complex object-oriented designs.

Rules of Virtual Functions in C++

Virtual function rules are important to ensure a consistent and structured approach while implementing dynamic polymorphism in C++. Here are the rules that must be followed while writing a virtual function in C++:

  • Virtual functions cannot be static and must be declared in the base class to be overridden in derived classes.
  • Friend functions can be virtual, offering access to private or protected members of the class.
  • To achieve runtime polymorphism, virtual functions should be accessed through pointers or references of the base class.
  • The prototype of virtual functions must match both the base and derived classes for proper overriding.
  • Overriding a virtual function in derived classes is optional; otherwise, the base class’s version is used.
  • While a class can have a virtual destructor, a virtual constructor is not permitted in C++.

How to Use a Virtual Function in C++

To use a virtual function in C++, follow these steps:

  • Define a virtual function in the base class by declaring it with the “virtual” keyword.
  • Implement the virtual function in the base class.
  • Optionally, override the virtual function in derived classes to provide specific implementations.
  • Access the virtual function through a pointer or reference to the base class to achieve dynamic binding at runtime.
  • Utilize the virtual function in your code to enable polymorphic behavior based on the actual object type.

Get 100% Hike!

Master Most in Demand Skills Now!

Example of a Virtual Function in C++

In C++, a virtual function enables runtime polymorphism, allowing a base class pointer to call overridden functions in derived classes. Let’s consider an example with a base class Shape and its derived classes Circle and Square, each having its own draw() method.

#include <iostream>
class Shape {
public:
    virtual void draw() { std::cout << "Drawing a Shape" << std::endl; }
};
class Circle : public Shape {
public:
    void draw() override { std::cout << "Drawing a Circle" << std::endl; }
};
class Square : public Shape {
public:
    void draw() override { std::cout << "Drawing a Square" << std::endl; }
};
int main() {
    Shape* shape1 = new Circle();
    Shape* shape2 = new Square();
    shape1->draw();  // Calls Circle's draw()
    shape2->draw();  // Calls Square's draw()
    delete shape1;
    delete shape2;
    return 0;
}

In the above example, Base Class ‘Shape’ contains a virtual function draw() that serves as an interface for its derived classes. This function is marked as virtual, indicating that it can be overridden by derived classes. Both derived classes, Circle and Square, inherit from the Shape class and override the draw() function with their specific implementations. Pointers of the base class type (Shape*) are used to hold derived class objects Circle and Square. When calling shape1->draw() or shape2->draw(), even though the pointers are of type Shape*, the appropriate derived class’s draw() method is invoked. This happens because of the implementation of late binding or runtime polymorphism by the virtual function. It allows the correct overridden method draw() of class Circle or Square to be called based on the actual object type.

Compile Time (Early Binding) Vs. Runtime (Late Binding) Behavior

This table summarizes the key distinctions between early binding and late binding behaviors by virtual functions based on characteristics in terms of method resolution, flexibility, performance, and usage in C++.

AspectCompile-Time (Early Binding)Runtime (Late Binding)
Method ResolutionResolved at compile timeExecuted until runtime (dynamically determined)
Decision TimingMethod call determined by pointer/reference typeMethod call determined by the object’s actual type
FlexibilityLimited polymorphism and extensibilityEnhanced polymorphism, allowing for code extensibility
PerformanceFaster execution due to static bindingSlightly slower execution due to dynamic binding
Function Call ResolutionBound directly to the method associated with the typeInvokes the appropriate derived class method
UsageNon-virtual functions and regular member functionVirtual functions enabling runtime polymorphism

Pure Virtual Function in C++

A pure virtual function in C++ is a virtual function that is declared in a base class but has no implementation provided in that class. It is denoted by assigning 0 to the function declaration, making it mandatory for any derived class to implement it. Classes containing pure virtual functions are known as abstract classes and cannot be instantiated; they are designed to serve as base classes for other classes to inherit from.

#include <iostream>
// Abstract class with a pure virtual function
class Shape {
public:
    // Pure virtual function
    virtual void area() = 0;
};
// Derived class implementing the pure virtual function
class Circle : public Shape {
public:
    void area() override {
        std::cout << "Area of circle: πr^2" << std::endl;
    }
};
int main() {
    // Shape* pointer to Circle object
    Shape* shape = new Circle();
    shape->area(); // Calls the overridden area() function in Circle
    delete shape; // Free memory
    return 0;
}

In the above example, the Shape class contains a pure virtual function area() with no implementation. The Circle class inherits from Shape and provides an implementation for the area() function. In the main() function, a pointer of type Shape is created and assigned the address of a Circle object. When shape->area() is called, it invokes the overridden area() function in Circle, printing the area of the circle.

Conclusion

Understanding virtual functions in C++ is fundamental for achieving polymorphic behavior and implementing runtime binding. They enable dynamic method resolution, allowing different classes to override base class functions and facilitating flexibility and extensibility in object-oriented programming. The concept of virtual functions enhances code reusability, scalability, and the creation of robust class hierarchies. Embracing virtual functions optimizes code structure and facilitates the development of efficient, maintainable software systems.

Course Schedule

Name Date Details
Python Course 14 Dec 2024(Sat-Sun) Weekend Batch View Details
21 Dec 2024(Sat-Sun) Weekend Batch
28 Dec 2024(Sat-Sun) Weekend Batch

About the Author

Senior Consultant Analytics & Data Science

Sahil Mattoo, a Senior Software Engineer at Eli Lilly and Company, is an accomplished professional with 14 years of experience in languages such as Java, Python, and JavaScript. Sahil has a strong foundation in system architecture, database management, and API integration.