Mezcla de herencia virtual y no virtual de una clase base

Este es el código:

struct Biology
{    
    Biology() { cout << "Biology CTOR" << endl; }
};

struct Human : Biology
{    
    Human() { cout << "Human CTOR" << endl; }
};

struct Animal : virtual Biology
{
    Animal() { cout << "Animal CTOR" << endl; }
};

struct Centaur : Human, Animal
{
    Centaur() { cout << "Centaur CTOR" << endl; }
};

int main()
{   
   Centaur c;

   return 0;
}

Este código imprime:

Biology CTOR
Biology CTOR
Human CTOR
Animal CTOR
Centaur CTOR

¿Por qué?

Desde que creamos unCentaur objeto, empezamos por construir elCentaur construyendoHuman, Animal y finalmenteCentaur (partimos de lo menos derivado a lo más derivado).

Empecemos desdeHuman: Human hereda deBiologyasí que llamamosBiologyEl constructor primero. Ahora esoHumanLa clase base está construida, finalmente podemos construir elHuman sí mismo. Pero en vez,Biology se construye de nuevo!

¿Por qué? ¿Qué está pasando detrás de escena?

Tenga en cuenta que fue completamente intencional irseAnimal heredando virtualmente deBiology y, al mismo tiempo, también fue un abandono intencionalHuman no virtualmente heredando deBiology.

Estamos resolviendo elDiamante temido de manera incorrecta:tanto humanos como animales deberían heredar virtualmente la biología para hacer que esto funcione

Tengo curiosidad.

Además, vea este código:

struct Biology
{    
    Biology() { cout << "Biology CTOR" << endl; }
};

struct Human : virtual Biology
{
    Human() { cout << "Human CTOR" << endl; }
};

struct Animal : Biology
{    
    Animal() { cout << "Animal CTOR" << endl; }
};

struct Centaur : Human, Animal
{
    Centaur() { cout << "Centaur CTOR" << endl; }
};

int main()
{   
   Centaur c;

   return 0;
}

Aquí tenemosHuman heredando virtualmente deBiology, mientrasAnimal está configurado para heredar de la "forma clásica".

Pero esta vez, la salida es diferente:

Biology CTOR
Human CTOR
Biology CTOR
Animal CTOR
Centaur CTOR

Esto porqueCentaur heredaprimero deHuman yentonces deAnimal.

Si el orden hubiera sido inverso, habríamos obtenido el mismo resultado que antes, en el primer ejemplo: dosBiology instancias que se construyen en una fila.

¿Cuál es la lógica de esto?

Intenta explicar tu camino, ya he revisado toneladas de sitios web que hablan sobre esto. Pero ninguno parece satisfacer mi solicitud.

Respuestas a la pregunta(3)

Su respuesta a la pregunta