Pregunta

Se produjo un problema extraño cuando intenté "resolver" un problema habitual de diamantes de forma habitual, utilizando la herencia virtual:

  A
 / \* both virtual
B   C
 \ /
  D

Sin embargo, mi clase base A no tiene constructor de incumplimiento, por lo que iba a llamarlo manualmente desde D. Sin embargo, cuando intento agregar una clase E a este diamante como C-heredado

  A
 / \* both virtual
B   C
 \ / \
  D   E

Todavía se necesita llamar al constructor de un constructor en E manualmente, es decir, C no es lo que crear una de E aunque no haya múltiples herencias ni diamante A-C-E.

class A                     
   {public: 
      A (int _N): N(_N) {};
      void show()
        {cout<<"A"<<N;} 
    protected:
      int N;
   }; 
class B: public virtual A   
   { public: 
       B(int n): A(2*n) {};
       void show()
        { cout<<"B"<<N;} 
   }; 
class C: public virtual A   
   { public: 
       C(int n): A(3*n) {};
       void show()
        { cout<<"C"<<N;} 
   }; 
class D: public B,C 
   { public: 
       D(): B(1), C(2), A(3) {};
       void show()
        { cout<<"D"<<N;} 
   }; 

class E: public virtual C
   { public:
       E(): C(1) {};
       void show()
        { cout<<"E"<<N;} 
   }; 

int main()
  {D d;       // OK
   A *a = &d; 
   a->show(); 

   E e;        // NOT OK, no function A::A() to call in E::E()
   A *a2 = &e;
   a2->show();
   return 0;
  } 

¿Es posible resolver este problema sin llamar al constructor de A de E? Necesito C para hacerlo correctamente :-).

o es posible no intentar resolver problemas de diamante en absoluto:

A   A
|   |  no virtual at all
B   C
 \ / \
  D   E

y aún intento declarar el objeto de la clase D con dos instancias de un, pero informarle al compilador a usar una de C al colar de d cada vez? Cuando intento agregar

using C::A

En la Declaración de D, aún produce un error de base no ambigua a.

¿Fue útil?

Solución

¿Es posible resolver este problema sin llamar al constructor de A de E?Necesito C para hacerlo correctamente: -).

El constructor para la clase más derivado (en este caso, E) es responsable de llamar al constructor para cualquier clase de base virtual.

El constructor de C no puede llamar al constructor de A porque C no es la clase más derivada.Las clases de base virtual se inicializan antes de Cualquier clase de base directa, por lo que E debe inicializarse por A antes de que pueda inicializar C.

Otros consejos

Sí, las llamadas de constructor de clase base virtual son a diferencia de la función virtual primordial:

  • puede anular una función virtual en una clase derivada;
  • Usted debe anular una función virtual solo si la función se anula en una de las clases base pero no en otras;
  • No se puede anular la lista de iniciales para las clases de base virtual del constructor de clase base.

Esto implica que:

  • En lo que respecta a la función de la función virtual, la herencia virtual no afecta a la herencia única en absoluto;
  • , pero cuando se trata de llamadas de constructor de clase base, la herencia virtual afecta a cada clase derivada.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top