Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 843
nitin_cherian Avatar asked Dec 07 '11 16:12

nitin_cherian


People also ask

What is a base class what is a derived class?

The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class.

Where is the derived class is derived from?

Derived ClassesA derived class is created from a previously defined class. Property and method overridingA property or method defined in a base class is accessible in the derived class. You can also modify the behavior of the base class properties and methods used by the derived class.

What a derived class can add?

The derived class inherits all of the properties of the base class. The derived class can add new members or change base class members.

When a class is derived from a base class it gets access to?

A derived class can access all the non-private members of its base class. Thus base-class members that should not be accessible to the member functions of derived classes should be declared private in the base class. Constructors, destructors and copy constructors of the base class.


2 Answers

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.

like image 71
smparkes Avatar answered Sep 30 '22 16:09

smparkes


Change

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

to

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

This is because you trying to call base1 constructor from a grand child derived2.

If you change the derivation of derived1 from base1 to be virtual. It is ok to call base1 from derived2. More details here.

like image 22
parapura rajkumar Avatar answered Sep 30 '22 18:09

parapura rajkumar