Virtual Function

A virtual function is a member function which is declared within base class and is overriden by 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.

  • They are mainly used to achieve Runtime polymorphism. The resolving of function call is done at Run-time.
  • Functions are declared with a virtual keyword in base class.

Rules for Virtual Functions

  • They Must be declared in public section of class.
  • Virtual functions cannot be static and also cannot be a friend function of another class.
  • Virtual functions should be accessed using pointer or reference of base class type to achieve run time polymorphism.
  • The prototype of virtual functions should be same in base as well as derived class.
  • They are always defined in base class and overridden in derived class. It is not mandatory for derived class to override, in that case base class version of function is used.
  • A class may have virtual destructor but it cannot have a virtual constructor.
// Virtual members example
#include <iostream>
using namespace std;

// Base class
class Polygon {
  protected:
    int width, height;
  public:

    void set_values (int a, int b) { 
      width=a; 
      height=b; 
    }
 
    // Virtual function
    virtual int area (){ 
      return 0; 
    }
};

// Derived Class
class Rectangle: public Polygon {
  public:
    int area (){ 
      return width * height; 
    }
};

// Derived Class
class Triangle: public Polygon {
  public:
    int area () { 
      return (width * height / 2); 
    }
};

int main () {
  Rectangle rect;
  Triangle trgl;
  Polygon poly;
  Polygon * ppoly1 = &rect;
  Polygon * ppoly2 = &trgl;
  Polygon * ppoly3 = &poly;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  ppoly3->set_values (4,5);
  cout << ppoly1->area() << '\n';
  cout << ppoly2->area() << '\n';
  cout << ppoly3->area() << '\n';
  return 0;
}

In this example, all three classes (PolygonRectangle and Triangle) have the same members: widthheight, and functions set_values and area.

The member function area has been declared as virtual in the base class because it is later redefined in each of the derived classes. Non-virtual members can also be redefined in derived classes, but non-virtual members of derived classes cannot be accessed through a reference of the base class: i.e., if virtual is removed from the declaration of area in the example above, the version of the base class would have been called instead.

Therefore, essentially, what the virtual keyword does is to allow a member of a derived class with the same name as one in the base class to be appropriately called from a pointer, and more precisely when the type of the pointer is a pointer to the base class that is pointing to an object of the derived class, as in the above example.

Abstract base classes

Abstract base classes are something very similar to the Polygon class in the above example. They are classes that can only be used as base classes, and thus are allowed to have virtual member functions without definition (known as pure virtual functions). The syntax is to replace their definition by =0 (an equal sign and a zero). Classes that contain at least one pure virtual function are known as Abstract base classes.

// Abstract class Polygon
class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b) { 
      width=a; 
      height=b; 
    }
 
    // Pure virtual function
    virtual int area () =0;
};

Abstract base classes cannot be used to instantiate objects. It can be used to create pointers to it, and take advantage of all its polymorphic abilities. For example

// Not allowed since Polygon is abstract base class 
Polygon mypolygon;

// Allowed for abstract base class
Polygon * ppoly1;