Virtual Function in C++


Reading time: 30 minutes

A virtual function is a member function which is declared within a base class and is re-defined(Overriden) by a derived class. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class’s version of the function.

Syntax

virtual return_type function_name()
{
     ...
}
  • Virtual functions ensure that the correct function is called for an object, regardless of the type of reference (or pointer) used for function call.
  • They are mainly used to achieve Runtime polymorphism
  • Functions are declared with a virtual keyword in base class.
  • The resolving of function call is done at Run-time.

Rules for Virtual Functions

  1. Virtual functions cannot be static and also cannot be a friend function of another class.
  2. Virtual functions should be accessed using pointer or reference of base class type to achieve run time polymorphism.
  3. The prototype of virtual functions should be same in base as well as derived class.
  4. They are always defined in base class and overridden in derived class. It is not mandatory for derived class to override (or re-define the virtual function), in that case base class version of function is used.
  5. A class may have virtual destructor but it cannot have a virtual constructor.

Example

Without virtual keyword:

#include<iostream> 
using namespace std; 
  
class base 
{ 
public: 
    void print () 
    { cout<< "print base class" <<endl; } 
  
    void show () 
    { cout<< "show base class" <<endl; } 
}; 
  
class derived:public base 
{ 
public: 
    void print () 
    { cout<< "print derived class" <<endl; } 
  
    void show () 
    { cout<< "show derived class" <<endl; } 
}; 
  
int main() 
{ 
    base *bptr; 
    derived d; 
    bptr = &d; 
      
    //Non-virtual function, binded at compile time 
    bptr->print();  
      
    // Non-virtual function, binded at compile time 
    bptr->show();  
}

Output :

print base class
show base class

From the above example we can conclude that if we have same function name and signature (function overriding) and no virtual keyword is present then the value or the output will be of parent class always even if the object we are using is of derived class.

With virtual keyword:

#include<iostream> 
using namespace std; 
  
class base 
{ 
public: 
    virtual void print () 
    { cout<< "print base class" <<endl; } 
  
    void show () 
    { cout<< "show base class" <<endl; } 
}; 
  
class derived:public base 
{ 
public: 
    void print () 
    { cout<< "print derived class" <<endl; } 
  
    void show () 
    { cout<< "show derived class" <<endl; } 
}; 
  
int main() 
{ 
    base *bptr; 
    derived d; 
    bptr = &d; 
      
    //virtual function, binded at run time 
    bptr->print();  
      
    // Non-virtual function, binded at compile time 
    bptr->show();  
}

Output :

print derived class
show base class

From the above example we can conclude that if we have same function name and signature (function overriding) then the value or the output will be of derievd class where virtual keyword is present in the defination else the value will be of parent class.

NOTE: If we have created a virtual function in the base class and it is being overridden in the derived class then we don’t need virtual keyword in the derived class, functions are automatically considered as virtual functions in the derived class.

Question

Consider the following code example:

#include<iostream>
using namespace std;
 
class Base
{
public:
    virtual void show() { cout<<" In Base n"; }
};
 
class Derived: public Base
{
public:
    void show() { cout<<"In Derived n"; }
};
 
int main(void)
{
    Base *bp = new Derived;
    bp->show();
 
    Base &br = *bp;
    br.show();
 
    return 0;
}

What is the output of the above code?

In Derived In Derived
In Derived In Base
In Base In Derived
In Base In Base
Since show() is virtual in base class, it is called according to the type of object being referred or pointed, rather than the type of pointer or reference.