Which instance will be called in multiple inheritance?

73 views Asked by At

I have 2 base classes (B1 and B2) which are derived from common Base class(B), where they have a common variable (let: int x; from base B), in 1st base x=0, in the 2nd base x=10 (default values given in B1,B2 constructors).

Now if I derive one more class (class D : virtual public B1, virtual public B2{}).

Here only one copy of x will be available as per virtual concept, now if I try to access x value with derived class object which instance of x I will get in O/p (x=0 or x=10), and why?

Thanks in advance.

3

There are 3 answers

0
ravi On

This is not the right place ( if you are not further deriving ) to use virtual base class. Perhaps you are mixing concepts.

class A;
class B : virtual public A
class C : virtual public A
class D : public B, public C

In this case it's meaningful to make base classes virtual as there are two paths to class A when you see through D.

Your case is :-

class B1
{
 public:
    int x;
};

class B2
{
  public :
     int x;
};

class D : public B1, publicB2
{
  public :
     void accessBase ()
     {
       this->x;             //error as ambigous.
       this->B1::x;         //fine it's B1's x.
       this->B2::x;         //fine it's B2's x.
     }
};
0
Tony Delroy On

here only one copy of x will be available as per virtual concept

No - the use of virtual bases ensures there's only one copy of B1 and one of B2, but there's only been one listed in the inheritance heirarchy anyway so the "virtuality" of the bases is irrelevant to the functionality here. Each base is a distinct class and both still have distinct x members. Therefore, you must disambiguate which you plan to use just as if the bases weren't virtual, using B1::x or B2::x.

Consider:

#include <iostream>

struct B1 { int x; };
struct B2 { int x; };
struct D : virtual B1, virtual B2 { };

int main()
{
    D d;
    d.B1::x = 2;
    d.B2::x = 4;
    std::cout << d.B1::x << ' ' << d.B2::x << '\n';
}

Output:

2 4

That shows they're independent variables. See the code running here

0
Lightness Races in Orbit On

Here only one copy of x will be available as per virtual concept

Here is the fundamental problem with your question's premise, because that's not true.

Unrelated bases cannot be "merged" just because you mark them virtual. If both B1 and B2 themselves derived from some VeryBase, then virtually deriving from B1 and B2 means you'd only have one copy of VeryBase:

                 VeryBase
                  /    \
                 /      \
                B1      B2    (inherited virtually)
                 \      /
                  \    /
                   \  /
                    \/
                     D

as opposed to:

          VeryBase      VeryBase
              \            /
               \          /
                B1      B2    (inherited normally)
                 \      /
                  \    /
                   \  /
                    \/
                     D

But that's not what you're doing here at all. There's no VeryBase — just two, independent, bases:

                B1      B2    (inherited normally or virtually; it doesn't matter)
                 \      /
                  \    /
                   \  /
                    \/
                     D

In this instance, your virtual inheritance is not making any difference at all, so you still have two int x members and you can access them independently in the usual way:

void D::foo()
{
   std::cout << B1::x << ' ' B2::x << std::endl;
}