Multiple inheritance
I have 2 base classes (B1 and B2) that are derived from a common base class (B) where they have a common variable (let's say: int x;
from base B), in 1st base x=0
, in 2nd base x=10
(values โโby defaults are given in constructors B1, B2).
Visually:
class B
{
int x;
protected:
B(int x) : x{x}{}
};
class B1 : public B
{
protected:
B1() : B(0){}
};
class B2 : public B
{
protected:
B2() : B(10){}
};
Now if I get another class:
class D : virtual public B1, virtual public B2
{
public:
D() : B1{}, B2{}{}
};
Here only one copy of x will be available according to the virtual concept, now if I try to access the value of x with a derived class, I get an instance of x in O / p ( x=0
or x=10
), and why?
source to share
To use virtual inheritance, base B
must be declared virtual in B1
both B2
. Without that, you have non-virtual inheritance B.
If you have non-virtual inheritance you have two bases B
in D
, so you cannot access x
in D
without getting it as B1::x
orB2::x
If you have virtual inheritance, you have only one B
and one x
, therefore, two assignments to him ( x=0
and x=10
) will be performed in any order in which you do them, and whichever one later will overwrite the value set by an earlier ( as with a simple variable x
with two assignments).
source to share
In your setup, as you have, B
it is not actually inherited in practice, because you need to declare virtual inheritance for B
both in B1
and in B2
(this should always happen at the lowest level if two "branches" are expected to merge above in the class inheritance hierarchy), i.e.
class B1 : virtual public B
{
protected:
B1() : B(0){}
};
class B2 : virtual public B
{
protected:
B2() : B(10){}
};
If you do this, the initialization B
will be completely different, as there are special rules for building virtual base classes:
In virtual inheritance, the virtual base class is always initialized with the most derived class. Thus, since you have implemented the constructor D
as
D() : B1(), B2(){}
and hence not calling the constructor explicitly B
, the compiler assumes that you want to call the default constructor B
. But your class B
doesn't have a default constructor, so you'll get a compiler error like this:
prog.cpp: In constructor โD::D()โ:
prog.cpp:31:20: error: no matching function for call to โB::B()โ
D() : B1(), B2(){}
^
Therefore, you will need to do something like
class D : public B1, public B2
{
public:
D() : B(99), B1(), B2(){}
};
and that also solves your question: the value x
will be what this class wants (in this case 99). Thus, there is no ambiguity.
PS: You can also see, your question is at the heart of why it makes sense to have a special rule about constructing a virtual base class from the most derived class.
source to share