motis10
motis10

Reputation: 2596

C++ constructor order while virtual inheritance

class Animal {
public:
    Animal(const char * color, int childs, float avgLifetime) {
        //Do something
    }
};

class Birds: virtual public Animal {
public:
    Birds(const char * color, int childs, float avgLifetime, float incubation)
    : Animal(color, childs, avgLifetime) {
        //Do something
    }
};

class Flamingo: public Birds {
public:
    Flamingo(const char * color, int childs, float avgLifetime, float incubation, float avgHeight)
    : Animal(color, childs, avgLifetime),
      Birds(color, childs, avgLifetime, incubation) {
        //Do something
    }
};

When I try to create new Flamingo I skipped the Animal constructor.
I guess it's because the Birds that heir virtual Animal.

I thought it will arrive in order:

Animal->Birds->Flamingo  

Why is it skip the Animal constructor?

Upvotes: 3

Views: 85

Answers (2)

jxh
jxh

Reputation: 70392

Since Birds uses virtual inheritance with Animal, then any derivation of Birds is also using virtual inheritance with Animal. In particular:

class Flamingo : public Birds { /* ... */ };

is implicitly equivalent to:

class Flamingo : virtual Animal, public Birds { /* ... */ };

And if you had written it explicitly, then you would have expected to add code to Flamingo to call the constructor on Animal (or allow Flamingo to implicitly invoke Animal's default constructor). Moreover, Flamingo's initialization of the Animal instance overrides Birds'.

So, the initialization is still AnimalBirdsFlamingo, but the Animal initialization is whatever Flamingo does, and Birds' initialization is skipped, since Animal is already initialized.

Upvotes: 2

Jarod42
Jarod42

Reputation: 217225

With virtual base, it is the most derived class which call the virtual base constructor.

So in your case:

class Flamingo: public Birds {
public:
    Flamingo(const char* color,
             int childs,
             float avgLifetime,
             float incubation,
             float avgHeight) :
        // Animal(), // it is this one which is called
        Birds(color, childs, avgLifetime, incubation)
    {}
    // ...
};

The one from Birds is ignored:

class Birds: virtual public Animal {
public:
    Birds(const char* color,
          int childs,
          float avgLifetime,
          float incubation) :
         Animal(color, childs, avgLifetime) // Not called for Flamingo
   {}
   //Do something
};

Upvotes: 0

Related Questions