In this guide, we will see what are virtual functions and why we use them. When we declare a function as virtual in a class, all the sub classes that override this function have their function implementation as virtual by default (whether they mark them virtual or not). Why we declare a function virtual? To let compiler know that the call to this function needs to be resolved at runtime (also known as late binding and dynamic linking) so that the object type is determined and the correct version of the function is called.
Lets take an example to understand what happens when we don’t mark a overridden function as virtual.
Example 1: Overriding a non-virtual function
See the problem here. Even though we have the parent class pointer pointing to the instance (object) of child class, the parent class version of the function is invoked.
You may be thinking why I have created the pointer, I could have simply created the object of child class like this: Dog obj; and assigned the Dog instance to it. Well, in this example I have only one child class but when we a big project having several child classes, creating the object of child class separately is not recommended as it increases the complexity and the code become error prone. More clarity to this after this example.
#include<iostream> using namespace std; //Parent class or super class or base class class Animal{ public: void animalSound(){ cout<<"This is a generic Function"; } }; //child class or sub class or derived class class Dog : public Animal{ public: void animalSound(){ cout<<"Woof"; } }; int main(){ Animal *obj; obj = new Dog(); obj->animalSound(); return 0; }
Output:
This is a generic Function
Example 2: Using Virtual Function
See in this case the output is Woof, which is what we expect. What happens in this case? Since we marked the function animalSound() as virtual, the call to the function is resolved at runtime, compiler determines the type of the object at runtime and calls the appropriate function.
#include<iostream> using namespace std; //Parent class or super class or base class class Animal{ public: virtual void animalSound(){ cout<<"This is a generic Function"; } }; //child class or sub class or derived class class Dog : public Animal{ public: void animalSound(){ cout<<"Woof"; } }; int main(){ Animal *obj; obj = new Dog(); obj->animalSound(); return 0; }
Output:
Woof