Порядок конструктора C ++ при виртуальном наследовании - PullRequest
3 голосов
/ 25 мая 2019
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
    }
};

Когда я пытаюсь создать новый Flamingo, я пропустил конструктор Animal.
Я думаю, это потому, что Birds этот наследник виртуальный Animal.

Я думал, что он прибудет в порядке:

Animal->Birds->Flamingo  

Почему пропускается конструктор Animal?

Ответы [ 2 ]

2 голосов
/ 25 мая 2019

Поскольку Birds использует виртуальное наследование с Animal, то любое наследование Birds также использует виртуальное наследование с Animal. В частности:

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

неявно эквивалентно:

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

И если бы вы написали это явно, то вы ожидали бы добавить код к Flamingo для вызова конструктора на Animal (или позволить Flamingo неявно вызывать конструктор Animal по умолчанию). Более того, Flamingo инициализация экземпляра Animal переопределяет Birds '.

Итак, инициализация по-прежнему Animal & rarr; Birds & rarr; Flamingo, но инициализация Animal - это то, что делает Flamingo, и инициализация Birds 'пропускается, поскольку Animal уже инициализирован.

0 голосов
/ 25 мая 2019

С виртуальной базой это самый производный класс, который вызывает конструктор виртуальной базы.

Так в вашем случае:

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)
    {}
    // ...
};

Тот из Птиц игнорируется:

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
};
...