Tutorial Study Image

C++ Virtual Function


June 4, 2023, Learn eTutorial
362

One of the most used programming languages in the world is C++. It is an expanded form of the C programming language and adheres to the OOPs principle to some extent. Even the fundamentals of OOPs are supported by C++, including encapsulation, inheritance, polymorphism, and others. You will be concentrating on C++ virtual functions in this tutorial because they are very essential for polymorphism.

In C++ what do you mean by a virtual function?

A member function that is declared in a base class and redefined (overridden) by a derived class is known as a virtual function That means the virtual function in C++ is a kind of a member function of a base class that can be redefined in a derived class in order to create polymorphism. The virtual keyword can be used to declare the function in the base class. Using a pointer or reference, you can call the virtual class and run the virtual version of the function in the derived class after declaring it in the base class. Therefore, it requests the compiler to create a function bind and determine the object's type at runtime (late binding or dynamic linkage).

In C++, a virtual function will always ensure that the proper function is called using a reference or pointer. The C++ programming language only permits the usage of a single pointer in order to refer to all the objects of the derived classes. The function which is in the base class will always be called since the pointer contains references to all the objects from which it was derived. This problem can be solved in C++ by using virtual functions, which assist in the run-time execution of the virtual version of the derived class.

When you use a pointer or a reference to the base class to refer to a derived class object, you can call a virtual function for that object and have the derived class's version of the function executed.

Properties of Virtual Functions

  • No matter what kind of reference (or pointer) is used to invoke a function, virtual functions make sure the right function is called for an object.
  • Their primary purpose is to implement runtime polymorphism.
  • In base classes, functions are declared using the virtual keyword
  • resolving of function calls that occur during runtime.

Rules What Are the Virtual Function Rules in C++?

Here are some guidelines to follow while creating a virtual function in C++. These rules are as follows:

  • Virtual functions can never be static.
  • A friend function of a different class can be a virtual function.
  • To accomplish runtime polymorphism, virtual functions should be accessed using a pointer or reference of the base class type.
  • Virtual functions should have the same prototype in both the base class and also for the derived class.
  • Each time, they are defined in the base class as well as overridden in the derived class. It is not necessary for the derived class to override (or re-define) the virtual function; in such a case, the function's definition from the base class is used.
  • Virtual constructors are not permitted in classes, although virtual destructors are permitted.
  • In base classes, functions are declared using the virtual keyword.
  • Using object pointers, virtual functions can be accessed.

An example of a virtual function in C++

The program demonstrates the runtime behavior of virtual functions.


#include<iostream>
using namespace std;

class base {
public:
 virtual void print()
 {
  cout << "Just print  the  base class\n";
 }

 void show()
 {
  cout << "Just show the base class\n";
 }
};

class derived : public base {
public:
 void print()
 {
  cout << "Just print the derived class\n";
 }

 void show()
 {
  cout << "Just show  the derived class\n";
 }
};

int main()
{
 base *bptr;
 derived d;
 bptr = &d;

 //The  Virtual function, binded at the runtime
 bptr->print();

 //The  Non-virtual function, binded at the compile time
 bptr->show();
 
 return 0;
}

 

Output:


Just print the derived class
Just show the base class

Explanation of the program

The only way to create runtime polymorphism is by using a pointer (or reference) of the base class type, as explained. A base class pointer can also point to both objects from the base class and those from derived classes. The base class pointer "bptr" in the code above contains the address of object "d" of the derived class.

Because the print() function is declared with a virtual keyword, it is going to be bound mainly at the runtime (output prints the derived class because the pointer is pointing to its object.) While show() is non-virtual, it shall be bound during the compile time.

Point to remember: If we defined a virtual function in the base class and override it in the derived class, Then we do not require the virtual keyword in the derived class; So the functions in the derived class will be automatically considered as the virtual functions.

Concept of VTABLE and VPTR in virtual functions

The VTABLE and VPTA concepts are covered here. If a class has a virtual function, the compiler performs two actions.

  • A virtual pointer (VPTR), which points to the class's VTABLE, is added as a data member of the class if an object of that class is created. Each time an object is generated, a new virtual pointer is added as a class's data member.
  • No matter if an object is generated or not, the class has a member called VTABLE which is a static array of function pointers. The addresses of each virtual function in that class are stored in the cells of this table.
C++ Virtual Function

The program shows the working of the Virtual Functions


#include<iostream>
using namespace std;

class base {
public:
 void fun_1() { cout << "base-1\n"; }
 virtual void fun_2() { cout << "base-2\n"; }
 virtual void fun_3() { cout << "base-3\n"; }
 virtual void fun_4() { cout << "base-4\n"; }
};

class derived : public base {
public:
 void fun_1() { cout << "derived-1\n"; }
 void fun_2() { cout << "derived-2\n"; }
 void fun_4(int x) { cout << "derived-4\n"; }
};

int main()
{
 base *p;
 derived obj1;
 p = &obj1;

 // Early binding it is  becausethe  fun1() is non-virtual
 // in base
 p->fun_1();

 // Late binding (RTP)
 p->fun_2();

 // Late binding (RTP)
 p->fun_3();

 // Late binding (RTP)
 p->fun_4();

 // Early binding, however because the pointer is of base type and the function is of a derived class,
 //  the function call is illegal and results in an error.
 
 return 0;
}

 

Output:


base-1
derived-2
base-3
base-4

Explanation of the program

To begin, we establish a base class pointer and initialize it with the address of the object of the derived class. The compiler creates a pointer as a data member of the class when we create an object of the derived class, and it contains the address of the VTABLE of a derived class.

The above example uses a similar concept of late and early binding. When the fun 1() function is called, the base class version of the function is used; fun 2() is overridden in the derived class, so the derived class version is used; fun 3() is not overridden in the derived class and is a virtual function, so the base class version is used; and fun 4() is not overridden, so the base class version is used.

Compile-Time Behaviour VS Runtime Behaviour of Virtual Functions in C++

  Compile-Time behavior Run-Time behavior

Alternative binding

Early binding

Late binding

How is it achieved

The type of pointer

Depending on the location where the pointer is pointing

What does a C++ pure virtual function mean?

In C++, a virtual function that does nothing is called a pure virtual function, also referred to as a do-nothing function. It is just used as a placeholder and contains no function definition (do-nothing function). It is mentioned in an abstract base class. These classes are incapable of declaring any objects of their own.

The syntax below is used to derive a pure virtual function in C++:


Virtual void class_name() = 0;
 

Example program for pure virtual function


#include <iostream>

using namespace std;

class Base{

    public:

    virtual void Output() = 0;  

};

class Derived : public Base{

    public:

    void Output()  

    {

        std::cout << "The class which is derived from the Base class." << std::endl;

    }

};

int main(){

    Base *bpointr;

    Derived dpointr;

    bpointr = &dpointr;

    bpointr->Output();  

    return 0;

}

 

Output:


The class which is derived from the Base class.

Conclusion

You learned about virtual functions in C++ in this tutorial along with some easy examples. Additionally, you have seen what a C++ pure virtual function is.

A pointer that always points to the base class is a problem that can be solved with virtual functions. You can visit our C++ Tutorial to learn more about these basic C++ principles. The lessons are made to make it easier for you to understand different C++ programming topics and concepts and to improve your C++ development skills.