virtual

Syntax:

    virtual return-type name( parameter-list );
    virtual return-type name( parameter-list ) = 0;
 
    class name : virtual parent_name {};

The virtual keyword can be used to create virtual functions (which can be overridden by derived classes) and to perform virtual inheritance.

Virtual functions

If the function is specified as a pure virtual function (denoted by the = 0), it must be overridden by a derived class.

For example, the following code snippet shows how a child class can override a virtual method of its parent, and how a non-virtual method in the parent cannot be overridden:

  class Base {
  public:
   void nonVirtualFunc() {
     cout << "Base: non-virtual function" << endl;
   }
   virtual void virtualFunc() {
     cout << "Base: virtual function" << endl;
   }
  };
 
  class Child : public Base {
  public:
   void nonVirtualFunc() {
     cout << "Child: non-virtual function" << endl;
   }
   void virtualFunc() {
     cout << "Child: virtual function" << endl;
   }
  };
 
  int main() {
   Base* basePointer = new Child();
   basePointer->nonVirtualFunc();
   basePointer->virtualFunc();
   return 0;
  }

When run, the following code displays:

  Base: non-virtual function
  Child: virtual function

Virtual inheritance

When used in inheritance, the virtual keyword forces the base class to become a direct base class of the derived class as well as any descendants of the derived class.

Virtual inheritance is most useful with multiple inheritance, when a derived class inherits a base class through two different paths (known as “the diamond problem”). For example:

class A {
 public:
  virtual void a();
};
 
class B : public A {
 public:
  virtual void b();
  // also contains a() by inheritance
};
 
class C :  public A {
 public:
  virtual void c();
  // also contains a() by inheritance
};
 
class D: public B, public C {
 public:
   virtual void d();
   // also contains b() and c() by inheritance,
   // as well as B::a() and C::a()
};

In the above example, class D contains two versions of the a method: one inherited through class B, one through class C. Virtual inheritance can be used to avoid this ambiguity:

class A {
 public:
  virtual void a();
};
 
class B : public virtual A {
 public:
  virtual void b();
  // also contains a() by inheritance
};
 
class C :  public virtual A {
 public:
  virtual void c();
  // also contains a() by inheritance
};
 
class D: public B, public C {
 public:
   virtual void d();
   // also contains b() and c() by inheritance,
   // as well as a single copy of a()
};

By using virtual inheritance, the parts of class A that class D inherits from B and C are considered the same, thus eliminating any ambiguity about what it means to call method a from D.

Related Topics: class