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?
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.
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.
The derived class inherits all of the properties of the base class. The derived class can add new members or change base class members.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With