C ++ Herencia múltiple: ¿por qué no trabajas?
-
28-10-2019 - |
Pregunta
Estoy tratando de encontrar un interesante problema de herencia múltiple.
El abuelo es una clase de interfaz con múltiples métodos:
class A
{
public:
virtual int foo() = 0;
virtual int bar() = 0;
};
Luego hay clases abstractas que están completando parcialmente esta interfaz.
class B : public A
{
public:
int foo() { return 0;}
};
class C : public A
{
public:
int bar() { return 1;}
};
La clase que quiero usar hereda de ambos padres y especifica qué método debe provenir de dónde mediante el uso de directivas:
class D : public B, public C
{
public:
using B::foo;
using C::bar;
};
Cuando trato de instanciar un DI recibe errores por tratar de instanciar una clase abstracta.
int main()
{
D d; //<-- Error cannot instantiate abstract class.
int test = d.foo();
int test2 = d.bar();
return 0;
}
¿Alguien puede ayudarme a comprender el problema y cómo utilizar mejor las implementaciones parciales?
Solución
No tienes herencia de diamantes. los B
y C
clases base de D
cada uno tiene el suyo A
Subobjeto de clase base porque no heredan virtualmente de A
.
Entonces, en D
, realmente hay cuatro funciones de miembros virtuales puros que deben implementarse: el A::foo
y A::bar
de B
y el A::foo
y A::bar
de C
.
Probablemente quieras usar la herencia virtual. Las declaraciones de clase y las listas de clases base se verían así:
class A
class B : public virtual A
class C : public virtual A
class D : public B, public C
Si no desea usar la herencia virtual, debe anular las otras dos funciones virtuales puras en D
:
class D : public B, public C
{
public:
using B::foo;
using C::bar;
int B::bar() { return 0; }
int C::foo() { return 0; }
};
Otros consejos
Necesitas hacer tus clases base virtual
para que puedan heredar adecuadamente. La regla general es que todas las funciones y clases de base no privadas deben ser virtual
A menos que sepa lo que está haciendo y desea deshabilitar la herencia normal para ese miembro/base.