Конструктор самого низкого базового класса Diamond Inheritance

Код выглядит следующим образом:

Код :

#include <iostream>

using namespace std;

class Animal{
   int a;

    public:
    Animal(int a) : a(a){}
    int geta(){return a;}
};

class Bird : virtual public Animal{
    string b;
    public:
    Bird(int a , string b) : Animal(a) , b(b){}
};

class Fish : virtual public Animal{
    int f;
    public:
    Fish(int a , int f) : Animal(a) , f(f){}
};

class Unknown : public Bird, public Fish{
    char u;
    public:
    Unknown(int a , int f , string b , char u )
     : Bird(a , b) , Fish(a , f) , u(u){}  //Problem
};

Вопрос :

1.) Как я буду инициализировать весь суперкласс, если будет создан экземпляр класса Unknown? Поскольку будет создан только один экземпляр Animal, как я могу избежать того, чтобы mysef дважды вызывал его конструктор?

Спасибо


person caramel1995    schedule 19.09.2012    source источник
comment
Если вы сталкиваетесь с шаблоном наследования ромба в реальном мире, пожалуйста, переосмыслите свой дизайн и посмотрите, не имеет ли больше смысла использовать композицию вместо наследования. В общем, вы должны предпочесть композицию наследованию.   -  person Rob K    schedule 20.09.2012
comment
@RobK Ерунда. Алмазные или общие базовые классы распространены в ООП.   -  person curiousguy    schedule 18.08.2015
comment
@curiousguy Я рад, что не работаю над проектами, над которыми работаете вы, если вы сталкиваетесь с наследованием ромбовидного узора. За 20 лет профессионального развития C++ мне ни разу не пришлось его использовать.   -  person Rob K    schedule 18.08.2015
comment
@RobK В чем проблема?   -  person curiousguy    schedule 18.08.2015
comment
Потому что, как я сказал выше, когда встречается ромбовидный узор, это обычно происходит потому, что кто-то наследует, когда должен сочинять. Это отражает плохой дизайн, который снижает ремонтопригодность. Я не скажу, что это никогда не было правильным, но я никогда не видел случая, чтобы это было так.   -  person Rob K    schedule 18.08.2015


Ответы (1)


Самый производный класс инициализирует любые виртуальные базовые классы. В вашей иерархии классов Unknown должен создать виртуальный базовый класс Animal (например, добавив Animal(a) в его список инициализации).

При создании объекта Unknown ни Fish, ни Bird не вызовут конструктор Animal. Unknown вызовет конструктор виртуальной базы Animal.

person James McNellis    schedule 19.09.2012
comment
если я вызову конструктор класса Animal в Unknown, как насчет Bird и Fish? Как я собираюсь инициализировать их значение соответственно - person caramel1995; 19.09.2012
comment
Они не будут вызывать конструктор Animal: только самый производный класс (в данном случае Unknown) может вызывать конструкторы любых виртуальных базовых классов. - person James McNellis; 19.09.2012