2011-01-08 22 views
6

que tiene la siguiente situación, en la foto es el gráfico de la herencia teórica de mis clases:herencia de interfaces similares en C++

Inheritance Graph

La idea es, básicamente, a

1) tienen dos clases base abstractas que se puede implementar en diferentes plataformas (en mi caso, dos sistemas operativos diferentes)

2) permiten que BBase se pueda colar por colada a ABase para poder manejar ambos igualmente a veces (por ejemplo, para contener instancias de ambos tipos) en una lista).

3) implementan ciertas funciones comunes en ABase y BBase.

Ahora, ¿cuál sería la mejor manera de representar esto en C++? A pesar de que admite una herencia múltiple, no es posible heredar varios niveles como este. El problema es que B hereda de A y BBase, que a su vez heredan de ABase. Simplemente traducir 1: 1 (siguiente código) en C++, un compilador de C++ (GNU) se quejan de que Abase :: foo() no está implementado en B.

class ABase 
{ 
public: 
    virtual void foo() = 0; 
    void someImplementedMethod() {} 
}; 

class BBase : public ABase 
{ 
public: 
    virtual void bar() = 0; 
    void someOtherImplementedMethod() {} 
}; 

class A : public ABase 
{ 
public: 
    A() {} 
    void foo() {} 
}; 

class B : public A, public BBase 
{ 
public: 
    B() : A() {} 
    void bar() {} 
}; 

int main() 
{ 
    B b; 
    return 0; 
} 

¿Cómo cambiar este modelo de herencia de hacer es compatible con C++?

EDIT: Flechas invertidas en el diagrama y corregidas "down-convertible" en "up-convertible".

+0

"¿Por qué no se puede colar a ABase?" te refieres a que se puede colar, ¿no? –

+0

Sí, gracias por la pista. Lo mismo ocurre con las flechas en el diagrama. – Johannes

Respuesta

7

Se puede utilizar directamente ese tipo de jerarquía en C++ mediante virtual inheritance:

class ABase{...}; 
class BBase : public virtual ABase {...}; 
class A  : public virtual ABase {...}; 
class B  : public A, public BBase {...}; 

Por supuesto, si usted planea en tener más niveles, que podría ser una buena idea utilizar la herencia virtual para B también, por lo obtendrías

class B  : public virtual A, public virtual BBase {...}; 
+0

Buen comentario sobre el uso de 'virtual' para' BBase' también. Es bueno decidir qué clases son interfaces en un diamante como este, y donde 'virtual' es lógicamente correcto. –

+0

¡Guau, tu respuesta fue increíblemente rápida! ¡Muchas gracias, la herencia virtual es exactamente lo que necesitaba! – Johannes

+0

Aunque si la 'clase A' es estrictamente una clase de implementación, no es necesario que sea una base 'virtual'. –