In C++, a virtual function is a member function that can be overridden by the derived class. It is declared in the base class that we redefine in a derived class. Using the virtual keyword, we can define the virtual function.
When we declare the function in the base class, we can utilize a pointer and reference to invoke the virtual class and run its virtual function in the derived class. It is also known as the virtual method.
A virtual function is used to inform the compiler to perform late binding or dynamic linkage on the function. It supports runtime polymorphism, which allows function calls to be resolved dynamically using virtual tables (vtables) and v-pointers (vptrs).
Syntax
It has the following syntax:
class baseClass_name {
public:
Virtual void funct_name() {
//code implementation
}
};
In this syntax, the baseClassname represents the name of the base class, and the functname represents the name of the given function.
C++ Virtual Function Example
Let us take an instance to demonstrate the virtual function in C++.
Example
#include <iostream>
using namespace std; //using standard namespace
class baseClass {
public: //Access Modifier
virtual void display() //declaring Virtual function
{
cout << "It is the print base class method\n";
}
void show()
{
cout << "It is the show base class method\n";
}
};
class derived : public baseClass {
public:
void display()
{
cout << "It is the print derived class method\n";
}
void show()
{
cout << "It is the show derived class method\n";
}
};
int main() //Main Function
{
baseClass* bptr;
derived d1;
bptr = &d1;
// The Virtual function at the runtime
bptr->display();
// Non-virtual function at the compile time
bptr->show();
return 0;
}
Output:
It is the print derived class method
It is the show base class method
Explanation
In this example, we have taken a baseClass that contains a virtual function print, and it also contains a non-virtual function show. In the main function, a baseClass pointer (bptr) is set to point to an object of class type derived (d1). When bptr->display is executed, the late binding takes place, which means the function invoked is the overridden function in the derived class.
Rules of Virtual Function
Several rules of virtual function in C++ are as follows:
- Virtual functions must be members of some class.
- Virtual functions cannot be static members. They can be accessed via objeccpp tutorialers.
- In the base class, a virtual function can have any access level (including public, private, and protected).
- The virtual functions can be a friend of another class.
- They can have any return type, number, and argument type.
- A virtual function should be defined in the base class, even though it is not used in the program.
- The prototypes of a virtual function of the base class and all the derived classes should be the same. If the two functions with the same name but different prototypes, C++ will consider them as overloaded functions.
- We cannot have a virtual constructor, but we can have a virtual destructor.
Virtual Table (vTable) and Virtual Pointer (vPtr)
In C++, the virtual table (vTable) is a hidden process that is mainly used to implement runtime polymorphism using virtual functions. In virtual function, every class has one vTable. Each object of that class has one hidden vPtr thacpp tutorials to the vTable. The vTable holds addresses of virtual functions that can be invoked on objects of that class.
On the other hand, the virtual pointer is a hidden pointer within every object of a class with virtual functions. The compiler includes it as a member function . It is used to point to the vTable of that class. When a virtual function is called in the program, the VPTR helps to find the correct function address in the VTable at runtime.
C++ vTable and vPtr Example
Let us take an example to illustrate the vTable and vPtr in C++.
Example
#include <iostream>
using namespace std; //using standard namespace
class Car { // Base class
public:
virtual void start() { // Virtual function
cout << "Car is starting..." << endl;
}
};
class RacingCar : public Car { // Derived class
public:
void start() override { // Overriding virtual function
cout << "RacingCar is starting with a loud roar!" << endl;
}
};
int main() //Main Function
{
Car* carPtr; //It is the base class pointer
RacingCar rc; //It is the derived class object
carPtr = &rc; //points base class pointer to derived class object
carPtr->start(); // Late binding occurs via vTable and vPtr
return 0;
}
Output:
RacingCar is starting with a loud roar!
Explanation
In this example, we have taken a base class Car defines a virtual function start, which is overridden in the derived class RacingCar. In the main function, a base class pointer carPtr points to a RacingCar object.
When carPtr->start is called, late binding occurs using the vTable and vPtr, which results in the RacingCar version of start being executed at runtime.
Late Binding/Dynamic Binding in C++
In C++, late binding is the mechanism where the function call is resolved during runtime. It occurs only when a virtual function is called using a pointer or reference to the base class. Therefore, the compiler determines the type of object at runtime and then binds the function call.
When a virtual function is invoked on an object via a pointer or reference to the base class, we can use the virtual function table (vtable) that is connected with the actual object at runtime. It allows us to execute the correct derived class.
C++ Late Binding Example
Let us take an example to illustrate the Late Binding in C++.
Example
#include <iostream>
using namespace std; //Using Standard Namespace
class Animal { //class
public:
virtual void display() { // base class
cout << "Animal color black\n";
}
};
class Dog : public Animal {
public:
void display() override { // derived class
cout << "Dog color gray\n";
}
};
int main() {
Animal* ptr;
Dog d;
ptr = &d;
ptr->display(); //Late Binding
return 0;
}
Output:
Dog color gray
Explanation
In this example, we have taken a base class, Animal, that defines a virtual function display. After that, the derived class Dog overrides the virtual function. The ptr ->display function calls the late binding, and the Dog class display function is implemented because the type dog is an actual object.
Pure Virtual Function in C++
In C++, the pure virtual function is an abstract method that has no implementation. A pure virtual function is also known as the "do-nothing" function. It is a function that is declared in the base class that has no function definition relative to the base class.
A class that contains the pure virtual function cannot be utilized to create an object directly. These types of classes are known as abstract base classes. The main objective of the base class is to provide the traits to the derived classes and to create the base pointer used for achieving the runtime polymorphism.
Syntax
It has the following syntax
class Class_Name {
public:
virtual function_type function_name() = 0; // Pure Virtual Function
};
C++ Pure Virtual Function Example
Let us take an example to illustrate the pure virtual function in C++.
Example
#include <iostream>
using namespace std; //using standard namespace
class Base //Abstract base class
{
public: //Access modifier
virtual void show() = 0; //Pure Virtual function
};
class Derived : public Base
{
public:
void show()
{
std::cout << "Derived class is derived from the base class." << std::endl;
}
};
int main() //Main Function
{
Base *bptr; //base class pointer
//Base b;
Derived d;
bptr = &d;
bptr->show();
return 0;
}
Output:
Derived class is derived from the base class.
Explanation
In this example, the base class contains the pure virtual function. Therefore, the base class is an abstract base class. We cannot create the object of the base class.
Advantages and Disadvantages of Virtual Functions in C++
Several advantages and disadvantages of virtual functions in C++ are as follows:
Advantages of Virtual Functions
- It enables the derivation function in the derived class, which allows method overriding.
- It allows the design of user-friendly applications with minimal restrictions on the introduction of new derived classes, i.e. existing base class code does not require alteration.
- It increases the flexibility in the execution of a program as the calling of a function is done during program execution instead of during the writing of code.
- It ensures full functionality of the derived class when it is stored in the base class pointer for virtual function cases.
- It is useful in GUI frameworks, game engines, and plugin-based architectures.
- The function call takes a long time because of the virtual mechanism, which makes it more complex for compilers to optimize because it does not know which function will be called.
- In a complex system, the virtual function can make it more difficult to find where a function has been called.
- Virtual functions can cause several problems with some optimization techniques, which reduces performance.
- In virtual function, every class contains a virtual table (vtable) that increases its main memory.
Disadvantages of Virtual Functions
C++ Virtual Function MCQs
1) Which of the following classes is used to redefine a virtual function in C++?
- Parent class
- Base class
- Derived class
- All of the above
2) In C++ late/dynamic binding, the function call is resolved during?
- Compile Time
- Runtime
- Infinite Time
- None of the above
3) What will be the output of the following program?
#include <iostream>
using namespace std;
class Car {
public:
virtual void display()
{
cout << "This is a car.";
}
};
class Speedcar : public Car {
public:
virtual void display()
{
cout << "This is a speed car.";
}
};
int main()
{
Speedcar sc;
sc.display();
return 0;
}
- This is a speed car.
- This is a car
- Runtime Error
- Syntax Error
4) Which of the following options is used to access virtual functions in C++?
- Array
- Variable
- Objeccpp tutorialers
- Object
5) What is the correct syntax of Pure Virtual Function in C++?
- pure virtual return_type func;
- virtual return_type func = 0;
- virtual return_type func;
- virtual return_type func pure;