Adding virtual removes the error : type 'base' is not a direct base of derived class

nitin_cherian picture nitin_cherian · Dec 7, 2011 · Viewed 30k times · Source

Conside the following sample code below:

#include <iostream>

using namespace std;

class base
{
   public:
      base()
      {
         cout << "ctor in base class\n";
      }
};

class derived1 : public base
{
   public:
      derived1()
      {
         cout <<"ctor in derived1 class\n";
      }
};

class derived2 : public derived1
{
   public:
      derived2() : base()
      {
         cout << "ctor in derived2 class\n";
      }
};

int main()
{
   derived2 d2obj;
   return 0;
}

This gives the error:

error: type `base' is not a direct base of `derived2'

Why is this error occurring? If i make the base class virtual, the error is no longer there. What is the reason for this?

Answer

smparkes picture smparkes · Dec 7, 2011

Because base is not a direct base of derived2. You have to give a constructor for your direct bases, derived1 in this case.

Virtual bases are the exception. They are always initialized in leaf classes, otherwise potentially you get multiple constructor calls for the same base. So if you make base virtual, not only can you initialize it in derived2, you must.

The issue arises when you have a derivation graph that is not a tree. IBM has a pretty picture. If you don't make the base (V in the example) virtual (everywhere) you'll have multiple copies. If you do make it virtual everywhere, you'll only have one copy, but then the direct children can not run the constructor (it would run > 1 time) and the leaf class must. For more details, best to search the web.