Virtual Functions & Polymorphism:


Virtual Functions are a key aspect of Runtime Polymorphism in C++. We previously covered Polymorphism, including Compile-Time Polymorphism. Now, we delve into Run-Time Polymorphism in this tutorial.

A Virtual Function is a function declared as virtual in a base class and redefined in one or more derived classes. This allows each derived class to have its own version of the virtual function.

When member functions share the same name in both the base and derived classes, virtual functions provide the capability for programmers to call the member function of different classes through the same function call, depending on the context. This feature is known as Polymorphism in C++ programming, a crucial aspect of Object-Oriented Programming.

C++ Copy to Clipboard  
#include<iostream>
using namespace std;

class Base // Base Class
{
public:
    void display()
    {
        cout << "Base Class" << endl;
    }
};

class Derived : public Base // Derived class using inheritance
{
public:
    void display() // Redefining the same function
    {
        cout << "Derived Class" << endl;
    }
};

int main()
{
    Base *ptr; // Pointer object of type Base
    Derived obj; // Object of type Derived

    ptr->display(); // Function calling using Base-Class object

    ptr = &obj; // Pointer points to Derived Class
    ptr->display(); // Call display using pointer to Derived class

    return 0;
}

In the above example, even if the object of the derived class is assigned to a pointer of the base class, the display()function of the base class is executed. To execute the member function of the Derived Class, we need to use the virtual keyword in the base class along with the display()function. Let's revisit the example using the virtualkeyword.

VIRTUAL - C++ Copy to Clipboard  
#include<iostream>
using namespace std;

class Base // Base Class
{
public:
    virtual void display() // Virtual Function
    {
        cout << "Base Class" << endl;
    }
};

class Derived : public Base // Derived class using inheritance
{
public:
    void display() // Redefining the same function
    {
        cout << "Derived Class" << endl;
    }
};

int main()
{
    Base *ptr; // Pointer object of type Base
    Derived obj; // Object of type Derived

    ptr->display(); // Function calling using Base-Class object

    ptr = &obj; // Pointer points to Derived Class
    ptr->display(); // Call display using pointer to Derived class

    return 0;
}

After making the function of Base virtual, ptr->display()will call the display()of the derived class depending upon the content of the pointer. This example demonstrates Runtime Polymorphism in C++ using virtual functions.

In C++ Programming, sometimes inheritance is used only for better visualization of data without needing to create any object of the base class. For instance, if we want to calculate the area of different objects like Circle and Square, we can inherit these classes from a Shape. However, we don't need to create any object of Shape. In such cases, we can declare Shape as an abstract class. If we try to create an object of an abstract class, the compiler shows an error.

A pure Virtual function or abstract function in C++ is a virtual function for which we don't provide an implementation, only declaration. If =0is added to a virtual function, it becomes a pure virtual function.

class Base {
   public:
      void display(); // Not a virtual function
      virtual void display(); // Virtual function but not pure
      virtual void display() = 0; // Pure virtual function
};

In the above example, Base is an Abstract class because it has a pure virtual function. No objects of the class Base can be directly created. Base is explicitly meant to be a base class. Let's have a complete example for Pure Virtual Function.

PURE VIRTUAL FUNCTION - C++ Copy to Clipboard  
#include <iostream>
using namespace std;

class Shape /* Abstract class */
{
protected:
    float l;

public:
    void get_data() /* This function is not virtual */
    {
        cin >> l;
    }

    virtual float area() = 0; /* Pure virtual function */
};

class Square : public Shape // Derived class
{
public:
    float area()
    {
        return l * l;
    }
};

class Circle : public Shape // Derived class
{
public:
    float area()
    {
        return 3.14 * l * l;
    }
};

int main()
{
    Square squ; // Object of type Square
    Circle cir; // Object of type Circle

    cout << "Enter length to calculate the area of a square: ";
    squ.get_data();
    cout << "Area of square: " << squ.area();

    cout << "\n\nEnter radius to calculate the area of a circle:";
    cir.get_data();
    cout << "Area of circle: " << cir.area();

    return 0;
}

Virtual Function supports Run-Time Polymorphism.When a Base Class has a virtual member function, any class that inherits from the base class can redefine the function with the same prototype. Thus, when the virtual function is called using a Base Class pointer, the compiler decides at runtime which version of the function (Base Class version or Overridden Derived class version) to call. This phenomenon is known as Run-Time Polymorphism.