2011-01-08 7 views
6

Ich habe folgende Situation dargestellt wird, ist die theoretischen Vererbungsgraphen meiner Klassen:Interface- wie Vererbung in C++

Inheritance Graph

Die Idee ist im Grunde zu

1) haben zwei abstrakte Basisklassen das kann auf verschiedenen Plattformen (in meinem Fall zwei verschiedene Betriebssysteme) implementiert werden

2) erlauben BBase, auf ABase umwandelbar zu sein, um in der Lage zu sein, beide gleichermaßen zu behandeln (zB um Instanzen beider Typen zu halten) in einer Liste).

3) implementieren Sie einige allgemeine Funktionalität in ABase und BBase.

Nun, was wäre der beste Weg, dies in C++ darzustellen? Obwohl Multiple-Vererbung unterstützt wird, ist meines Wissens nach keine Multi-Level-Vererbung möglich. Das Problem ist, dass B von A und BBase erbt, die beide wiederum von ABase erben. Übersetzung dieses einfach 1: in B. 1 (folgenden Code) in C++, C++ Compiler (GNU) wird diese ABASE :: foo beschweren() nicht implementiert ist

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; 
} 

Wie würden Sie dieses Vererbungsmodell ändern zu machen es kompatibel zu C++?

EDIT: Inverse Pfeile im Diagramm und korrigiert "down-castable" zu "up-castable".

+0

"BBase, um zu ABase down-castable" Sie meinen up-castable, oder? –

+0

Ja, danke für den Hinweis. Das Gleiche gilt für die Pfeile im Diagramm. – Johannes

Antwort

7

Sie direkt diese Art von Hierarchie in C++ unter Verwendung virtual inheritance verwenden können:

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

Natürlich, wenn Sie mehrere Ebenen auf, die planen, könnte es eine gute Idee, auch für B virtuelle Vererbung zu verwenden, so Sie würden

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

Guter Kommentar über die Verwendung von 'virtual' für' BBase'. Es ist gut zu entscheiden, welche Klassen in diamonds so sind und wo also 'virtual' logisch korrekt ist. –

+0

Wow, deine Antwort kam blitzschnell! Vielen Dank, virtuelle Vererbung ist genau das, was ich brauchte! – Johannes

+0

Wenn "Klasse A" streng genommen eine Implementierungsklasse ist, besteht keine Notwendigkeit für eine "virtuelle" Basis. –