1

I cannot figure out what would happen in the following scenario:

class MBase {
    public:
       MBase(int) {}
       virtual char* vf() const = 0;
       virtual ~MBase() {}
};

class D1 : public MBase { //NOT VIRTUAL!!!
   public:
   D1() : MBase(1) {}
   char* vf() const { return "D1"; }
};

class D2 : virtual public MBase {
    public:
        D2() : MBase(2) {}
        char* vf() const { return "D2"; }
};

class Bottom : public D1, public D2 {
  public:
    char* vf() const { return "Bottom"; }
}

Base* b = new Bottom();  

In the original definition of the diamond both D1 and D2 were inheriting virtually from MBase, but here only one is. Would we still have two separate subobjects in Bottom object and therefore, the last line will not compile as compiler won't know which subobject to use?

Bober02
  • 15,034
  • 31
  • 92
  • 178

2 Answers2

2

This is specified in section 10.1.4 of the C++03 standard. Virtual and non-virtual bases are independent, so there will be one of each.

It is easy to see this by expanding your example:

class MBase {
    public:
       MBase(int arg) { cerr << "MBase::MBase(" << arg << ")\n"; }
       virtual const char* vf() const = 0;
       virtual ~MBase() {}
};

class D1 : public MBase { //NOT VIRTUAL!!!
   public:
   D1() : MBase(1) {}
   const char* vf() const { return "D1"; }
};

class D2 : virtual public MBase {
    public:
        D2() 
        : MBase(2) // This doesn't get used in this example because
                   // it is the responsibility of the most-derived
                   // class to initialize a virtual base, and D2 isn't
                   // the most-derived class in this example.
        {
        }
        const char* vf() const { return "D2"; }
};

class Bottom : public D1, public D2 {
  public:
    Bottom() 
    : MBase(5) // D1 and D2 default constructors are called implicitly.
    { 
    }
    const char* vf() const { return "Bottom"; }
};

int main(int argc,char **argv)
{
  Bottom b;
  return 0;
}

Outputs:

MBase::MBase(5)
MBase::MBase(1)
Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
  • Why is the constructor of D2 never invoked? – Bober02 Apr 14 '12 at 17:57
  • @Bober02: The D2 constructor gets called, but D2 doesn't call the constructor of the virtual base, even though it looks like it does. I've added some explanation in my answer. – Vaughn Cato Apr 14 '12 at 18:05
1

I think you problem is similar to this one... Basically, each objet has their own base object of mBase class...

Diamond inheritance

Regards, Erwald

Community
  • 1
  • 1
Erwald
  • 2,118
  • 2
  • 14
  • 20