Virtual Function in C++: Everything You Need to Know

By | January 13, 2024

Varun Saharawat is a seasoned professional in the fields of SEO and content writing. With a profound knowledge of the intricate aspects of these disciplines, Varun has established himself as a valuable asset in the world of digital marketing and online content creation.


Virtual Function in C++

Virtual Function in C++ exists in a base class and can be redefined or overridden in a derived class. The primary purpose of virtual functions is to ensure that, irrespective of the reference or pointer type used. Keep reading to know more!

Virtual Function in C++: For any C++ developer who has worked with polymorphism, virtual functions are likely a familiar concept. However, their name can often be misleading – what exactly does “virtual” mean in this context? While the term may seem abstract, virtual functions serve an important low-level purpose that programmers rely on every day without even realizing it.

C++ with DSA
C++ with DSA

Virtual functions allow classes related by inheritance to share a common interface while still maintaining separate implementations – this is the very core of polymorphism in C++. Without virtual functions, polymorphism simply would not be possible.

We highly recommend our C++ with DSA course, taught by our expert and compassionate instructors who are passionate about sharing their knowledge and experience with others. And as a token of appreciation towards our readers, we are offering an exclusive discount on this course through our “READER” coupon code. So don’t wait any longer, join our community of learners today and start mastering C++ with DSA!

Virtual Function in C++ Example

A virtual function in C++ is a member function declared within a base class that can be redefined (or overridden) in a derived class. This feature enables polymorphism, where you can achieve different functionalities for the same function depending on the context of the object it is called upon.

  • Declaration: To declare a function as virtual, you use the virtual keyword in the base class.
  • Overriding: Derived classes can provide a specific implementation of the virtual function using the same signature.
  • Polymorphism: This allows you to treat objects of different classes through a common interface, leading to polymorphic behavior.
  • Dynamic Dispatch: The use of virtual functions enables dynamic dispatch, meaning the appropriate function is called based on the object type at runtime.

Virtual functions play a crucial role in achieving runtime polymorphism in C++. Let’s explore a simple example to demonstrate the use of virtual functions in C++.

#include <iostream>

// Base class definition

class Base {

public:

    // Virtual function

    virtual void display() {

        std::cout << “This is the Base class display method.” << std::endl;

    }

};

// Derived class inheriting from Base

class Derived : public Base {

public:

    // Overriding the virtual function from Base class

    void display() override {

        std::cout << “This is the Derived class display method.” << std::endl;

    }

};

int main() {

    // Base class pointer pointing to Base class object

    Base* basePtr;

    // Derived class object

    Derived derivedObj;

    // Pointing basePtr to derivedObj (Upcasting)

    basePtr = &derivedObj;

    // Accessing the virtual function using basePtr

    // This will invoke the display method of Derived class due to dynamic binding

    basePtr->display();

    return 0;

}

Explanation:

  • Base Class (Base): We define a base class Base with a virtual function display(). The virtual keyword indicates that this function can be overridden in derived classes.
  • Derived Class (Derived): We define a derived class Derived that inherits from the Base class. Inside Derived, we override the display() function.
  • Dynamic Binding: In the main() function, we create a pointer basePtr of type Base. However, we assign its address to a Derived object (derivedObj), which is a classic example of upcasting.
  • Virtual Function Invocation: When we invoke the display() method using the basePtr, it calls the display() method of the Derived class, thanks to dynamic binding, demonstrating polymorphic behavior.

When you run this C++ program, the output will be:

This is the Derived class display method.

Also Read: Top 50 C++ Project Ideas For Beginners & Advanced

Pure Virtual Function in C++ With Example

A pure virtual function is a function declared in a base class that has no definition relative to that class and is declared using the virtual keyword and assigned to 0. A class containing a pure virtual function is considered an abstract class, and it cannot be instantiated.

Usage:

  • Abstract Class: A class that has at least one pure virtual function is known as an abstract class. An abstract class cannot be instantiated, meaning you cannot create an object of an abstract class.
  • Override in Derived Classes: Any derived class that inherits from an abstract class containing a pure virtual function must provide a concrete implementation (definition) for that pure virtual function unless it too is to be abstract.

Syntax:

virtual return_type function_name() = 0;

Example:

#include <iostream>

// Abstract Base Class

class Shape {

public:

    // Pure Virtual Function

    virtual void area() = 0;

};

// Derived class Circle inherits from Shape

class Circle : public Shape {

private:

    double radius;

public:

    // Constructor

    Circle(double r) : radius(r) {}

    // Implementation of pure virtual function area for Circle

    void area() override {

        std::cout << “Area of Circle: ” << 3.14 * radius * radius << std::endl;

    }

};

// Derived class Rectangle inherits from Shape

class Rectangle : public Shape {

private:

    double length, breadth;

public:

    // Constructor

    Rectangle(double l, double b) : length(l), breadth(b) {}

    // Implementation of pure virtual function area for Rectangle

    void area() override {

        std::cout << “Area of Rectangle: ” << length * breadth << std::endl;

    }

};

int main() {

    // Shape* pointer array to demonstrate polymorphism

    Shape* shapes[2];

    // Creating Circle and Rectangle objects

    Circle c(5);

    Rectangle r(4, 6);

    // Assigning address of Circle and Rectangle objects to Shape pointers

    shapes[0] = &c;

    shapes[1] = &r;

    // Calling area() method using Shape pointers

    shapes[0]->area();  // Outputs area of Circle

    shapes[1]->area();  // Outputs area of Rectangle

    return 0;

}

Explanation:

  1. Shape Class: The Shape class is an abstract base class with a pure virtual function area().
  2. Circle & Rectangle Classes: These are derived classes that provide a concrete implementation for the area() function inherited from the Shape class.
  3. Main Function: In the main() function, we create instances of the Circle and Rectangle classes. We assign their addresses to an array of Shape pointers. Using these pointers, we call the area() method, which demonstrates polymorphic behavior, invoking the appropriate version of the method based on the object type.

When executed, the program will display the areas of both the circle and the rectangle, illustrating the usage and importance of pure virtual functions in achieving polymorphism and abstraction in C++.

Rules for Virtual Function in C++

Virtual functions are a critical feature in C++ that enables polymorphism and facilitates dynamic binding during runtime. To effectively use virtual functions and harness their capabilities, it’s essential to understand the specific rules governing their behavior and implementation. Here’s a detailed exploration of the rules for virtual functions in C++:

1) Non-Static Nature:

  • Cannot Be Static: One fundamental rule to remember is that virtual functions cannot be static. The static keyword in C++ signifies that the function belongs to the class rather than an instance. Since virtual functions require dynamic linkage and late binding, they must be non-static members of the class.

2) Friendship with Classes:

  • Friend Function Capability: While it might seem counterintuitive, a virtual function can indeed be declared as a friend function of another class. This relationship allows the friend class to access and possibly override the virtual function’s behavior, adhering to the object-oriented design principles.

3) Access via Base Class Pointer or Reference:

  • Pointer or Reference Accessibility: To achieve the benefits of runtime polymorphism, virtual functions must be accessed using a pointer or reference of the base class type. This approach ensures that the correct overridden function in the derived class gets invoked based on the actual object type during runtime.

4) Consistent Prototype:

  • Uniform Function Prototype: The prototype of virtual functions should remain consistent across both the base and derived classes. This consistency ensures that the derived class’s overridden function maintains the same signature as the base class’s virtual function, facilitating seamless polymorphic behavior.

5) Base Class Definition & Derived Class Override:

  • Definition and Override Dynamics: Virtual functions are typically defined in the base class and can be overridden in derived classes. However, it’s essential to note that overriding is not mandatory. If a derived class chooses not to override a virtual function, the base class’s version of the function will be invoked by default during runtime.

6) Virtual Destructor vs. Virtual Constructor:

  • Destructor and Constructor Constraints: While a class in C++ can have a virtual destructor, enabling dynamic deallocation and preventing memory leaks in polymorphic hierarchies, it’s crucial to understand that a virtual constructor is not permissible in C++. The concept of a virtual constructor contradicts the language’s design principles, given the static nature of object creation and constructor invocation.

By adhering to these essential rules for virtual functions in C++, developers can effectively harness the power of polymorphism, dynamic binding, and object-oriented design principles. Understanding these rules ensures that you leverage virtual functions’ capabilities while maintaining consistency, clarity, and robustness in your C++ applications.

Use of Virtual Function in C++

Virtual functions are a cornerstone feature of object-oriented programming (OOP) in C++. They play a pivotal role in enabling polymorphism, which is one of the core principles of OOP. Here are some significant uses and advantages of virtual functions in C++:

1) Polymorphism:

  • Runtime Polymorphism: Virtual functions facilitate runtime polymorphism, where the appropriate function to be called is determined at runtime based on the object’s actual type rather than its declared type. This allows for more dynamic and flexible code behavior.

class Animal {

public:

    virtual void sound() {

        cout << “Animal makes a sound\n”;

    }

};

class Dog : public Animal {

public:

    void sound() override {

        cout << “Dog barks\n”;

    }

};

int main() {

    Animal* animal = new Dog();

    animal->sound();  // Output will be “Dog barks”

    return 0;

}

2) Base Class Pointers and Derived Class Objects:

  • Use with Base Class Pointers: Virtual functions allow base class pointers to point to derived class objects and invoke the derived class’s overridden methods. This flexibility is essential for achieving runtime polymorphic behavior.

3) Function Overriding:

  • Override Base Class Methods: Virtual functions enable derived classes to provide their specific implementation of a base class method. This feature allows for the creation of a common interface in the base class, with each derived class providing its unique behavior.

4) Facilitates Dynamic Binding:

  • Late Binding: Virtual functions facilitate late binding or dynamic binding. The correct function to be invoked is determined at runtime, based on the object’s actual type. This mechanism promotes flexibility and adaptability in code execution.

5) Enables Abstraction:

  • Abstraction and Encapsulation: Using virtual functions, you can define a base class with abstract methods that provide a high level of abstraction. Derived classes then implement these methods, encapsulating their specific functionalities while adhering to the base class’s contract.

6) Extensibility and Maintainability:

  • Enhances Code Reusability: By using virtual functions, you can design code that is more reusable, extensible, and maintainable. New derived classes can be added with minimal modifications to the existing codebase, adhering to the open/closed principle of software design.

7) Interface Definition:

  • Defines Interfaces: Virtual functions allow you to define interfaces in base classes that provide a blueprint for derived classes. This approach ensures that derived classes adhere to a specific contract, promoting consistency and cohesion in your object-oriented design.

Virtual functions in C++ offer a robust mechanism for implementing polymorphism, enabling dynamic binding, promoting code reusability, and facilitating a more flexible and maintainable object-oriented design. By leveraging virtual functions, developers can create more adaptable, scalable, and robust applications in C++.

Also Read: A Href Links: What They Are & How to Use Them

Working of Virtual Functions in C++

Virtual functions are a crucial feature in C++ that facilitates runtime polymorphism, a core principle of object-oriented programming (OOP). Understanding how virtual functions work is essential for developers aiming to leverage polymorphism effectively. Below is a detailed explanation of how virtual functions operate in C++.

Basics of Virtual Functions:

In C++, a virtual function is a member function declared in a base class with the virtual keyword. The primary objective of using virtual functions is to allow derived classes to provide their own implementation while invoking the correct function based on the actual object type at runtime, rather than compile-time.

Mechanism Behind Virtual Functions:

  • V-Table (Virtual Table): When a class contains one or more virtual functions, the compiler generates a v-table for that class. The v-table is an array of function pointers pointing to the virtual functions of the class. Each object of a class with virtual functions contains a hidden pointer (usually called the vptr) that points to its corresponding v-table.
  • Late Binding: When you call a virtual function using a base class pointer or reference, the C++ compiler ensures that the correct function corresponding to the actual object type (base or derived) is called. This process is known as late binding or dynamic binding because the function to call is determined at runtime.

Example:

Let’s consider a simple example involving a base class Animal and a derived class Dog:

#include <iostream>

// Base class

class Animal {

public:

    virtual void sound() {

        std::cout << “Animal makes a sound\n”;

    }

};

// Derived class

class Dog : public Animal {

public:

    void sound() override {

        std::cout << “Dog barks\n”;

    }

};

int main() {

    Animal* animalPtr;

    Dog dogObj;

    animalPtr = &dogObj; // Assigning address of derived class object to base class pointer

    // Call sound method using base class pointer

    animalPtr->sound();  // Output will be “Dog barks”

    return 0;

}

Steps Involved:

  1. Compilation: When you compile the above code, the compiler creates a v-table for both the Animal and Dog classes because sound() is a virtual function.
  2. Runtime Execution: When animalPtr->sound(); is executed, the program looks up the v-table pointer (vptr) in the Animal object. Since animalPtr points to a Dog object, the vptr will point to the Dog v-table.
  3. Function Call: Using the vptr, the program then fetches the correct function address from the Dog v-table and executes the Dog class’s version of the sound() function, demonstrating the power of late binding.

Advantages:

  • Flexibility: Allows derived classes to override base class methods, enabling polymorphic behavior.
  • Extensibility: Facilitates adding new derived classes without modifying the existing base class code.
  • Dynamic Binding: Ensures that the correct function is called based on the actual object type, promoting efficient and flexible code design.

Virtual functions in C++ play a pivotal role in implementing runtime polymorphism by dynamically binding the correct function calls based on the actual object type, enhancing code reusability, flexibility, and maintainability.

Also Read: What is a 301 Redirect, and When Should You Use One?

Virtual Function in Polymorphism

In C++, a virtual function is a function in a base class that is declared using the keyword virtual. When a derived class inherits from this base class and provides its own definition for this function, the derived class’s function is called, not the base class’s function, depending on the object type pointed by the base class pointer.

How Virtual Functions Work:

  1. Polymorphism: When a base class pointer points to a derived class object and a virtual function is called through that pointer, the derived class’s version of the function is executed, achieving runtime polymorphism.
  2. Dynamic Binding: The mechanism by which the appropriate function is called is determined at runtime (dynamic binding) rather than compile-time (static binding).

Example:

#include <iostream>

// Base class

class Animal {

public:

    virtual void sound() {

        std::cout << “Animal makes a sound\n”;

    }

};

// Derived class

class Dog : public Animal {

public:

    void sound() override {

        std::cout << “Dog barks\n”;

    }

};

int main() {

    Animal* animalPtr;

    Dog dogObj;

    animalPtr = &dogObj; // Pointing to derived class object

    // Call sound method using pointer

    animalPtr->sound();  // Output will be “Dog barks”

    return 0;

}

In this example, even though the pointer animalPtr is of type Animal, it points to an object of type Dog. When the sound() method is invoked through this pointer, the Dog class’s version of the function is executed, demonstrating the behavior of virtual functions in achieving polymorphism.

Virtual functions enable runtime polymorphism by allowing the appropriate derived class function to be called through a base class pointer or reference, based on the object type being pointed to or referenced.

We would like to leave you with a personal recommendation- enroll in the C++ with DSA course by Physics Wallah. This course not only covers all aspects of C++ in a structured manner but also includes valuable lessons on data structures and algorithms. And as a gesture of gratitude towards our readers, use the coupon code “READER” to avail an exclusive discount on the course fee.

Virtual Function in C++ FAQs

What is a virtual function in C++?

A virtual function in C++ is a function within a base class that is declared using the virtual keyword. When this function is redefined in a derived class, the version to be called is determined by the type of object pointed or referred to, not by the type of pointer or reference.

What is virtual function in C++ medium?

It seems like you're referencing a specific source or platform with "medium." However, in the context of C++, a virtual function remains the same: it's a function declared in a base class that can be overridden in derived classes to achieve runtime polymorphism.

What is the difference between virtual class and virtual function?

There's no concept of a "virtual class" in C++. Perhaps you meant an "abstract class" or a "base class." A virtual function is a member function of a class that is declared within a base class using the virtual keyword and can be overridden by derived classes. In contrast, a virtual class does not exist; instead, we have virtual functions within classes.

What is a virtual function in polymorphism?

In the context of polymorphism in C++, a virtual function allows a derived class to provide its specific implementation of a function that is already defined in its base class. This mechanism ensures that when a function call is made using a base class pointer or reference, the correct version of the function corresponding to the derived class object being pointed to or referred to is invoked, achieving runtime polymorphism.

Telegram Group Join Now
WhatsApp Channel Join Now
YouTube Channel Subscribe
Scroll to Top
close
counselling
Want to Enrol in PW Skills Courses
Connect with our experts to get a free counselling & get all your doubt cleared.