3

Betrachten Sie die folgende Architektur:C++ mehrere Diamanten Vererbung und rein virtuelle Funktionen

class A //abstract interface 
{ 
    public: 
    virtual void f() = 0; 
}; 
class AA : public A //abstract interface 
{ 
    public: 
    virtual void g() = 0; 
}; 
class AAA : public AA //abstract interface 
{ 
    public: 
    virtual void h() = 0; 
}; 

class B : public A // implementation class 
{ 
    public: 
    void f() override {}; 
}; 
class BB : public B, public AA {}; // implementation class 
{ 
    public: 
    void g() override {}; 
}; 
class BBB : public BB, public AAA {}; // implementation class 
{ 
    public: 
    void h() override {}; 
}; 

Als solche BB und BBB virtuelle Klassen sind, weil f von BB nicht außer Kraft gesetzt wird, und weder f noch g sind von BBB. Mein Wunsch ist es, BB und BBB zu instantiieren (so dass BB und BBB die Überschreibung von f verwenden, die durch B definiert ist, und BBB die Überschreibung von g verwendet, die durch BB definiert ist).

Die Frage ist: die Vererbungsbeziehungen als virtual markiert werden soll BB und BBB zu instanziiert?

Die Vererbungsdiagramm sollte idealerweise so aussehen:

A 
|\ 
| \ 
| \ 
AA B 
| \ | 
| \ | 
AAA BB 
    \ | 
    \ | 
    BBB 

Die Idee hinter dieser Konstruktion ist, dass A, AA und AAA-Schnittstellen beschreiben inkrementelle Leistungsstufen. B, BB und BB sind eine entsprechende inkrementelle Implementierung. (So ​​dass BB zum Beispiel alles definiert, was von AA benötigt wird und auch, was in B)

+0

Ihr den virtuellen Modifikator in Ihre Klassendefinitionen fehlen, glaube ich, sonst Ihre ganze Frage macht keinen Sinn. Details sind wichtig –

+0

Natürlich meinte ich den virtuellen Modifikator zu den FUNCTIONS –

Antwort

1

wenn A AA AAA wirklich nur Schnittstellen sind, ich meine, sie haben keine Mitglieder, dann brauchen Sie keine Vererbung, Implementieren Sie nur Schnittstellen und rufen Sie sie aus Basisklassen auf. Was Sie in B für Schnittstelle A implementiert haben, muss auch in BB implementiert sein, dann rufen Sie B:pureVirtual() in BB. Sonst sollte es so sein; (Dann sollten Sie einen Blick auf: 'class1' : inherits 'class2::member' via dominance)

class A 
{ 
public: 
    virtual void f() = 0; 
}; 
class AA : virtual public A 
{ 
public: 
    virtual void g() = 0; 
}; 
class AAA : virtual public AA 
{ 
public: 
    virtual void h() = 0; 
}; 

class B : virtual public A 
{ 
public: 
    void f() override { } 
}; 
class BB : public B, virtual public AA 
{ 
public: 
    void g() override { } 
}; 
class BBB : public BB, public AAA 
{ 
public: 
    void h() override { } 
}; 

Edit: (Ohne virtuelle Vererbung)

class A //abstract interface 
{ 
public: 
    virtual void f() = 0; 
}; 
class AA : public A //abstract interface 
{ 
public: 
    virtual void g() = 0; 
}; 
class AAA : public AA //abstract interface 
{ 
public: 
    virtual void h() = 0; 
}; 

class B : public A // implementation class 
{ 
public: 
    void f() override {} 
}; 
class BB : public B, public AA // implementation class 
{ 
public: 
    void g() override {} 
    void f() override { B::f(); } 
}; 
class BBB : public BB, public AAA // implementation class 
{ 
public: 
    void h() override {} 

    void g() override { BB::g(); } 
    void f() override { BB::f(); } 
}; 
+0

Aber dann 'void g() überschreiben {BB :: g(); } 'ist ein Override von g, das BBs Override aufruft. Können wir nicht einfach sagen, dass wir BBs Definition von g direkt verwenden wollen? Damit ist der Benutzer, der BBB implementiert, nicht versucht, g zu manipulieren. –

+0

@MarsyaKaustenstein Wenn Sie andere Dinge in 'BBB: g()' implementieren möchten, können Sie. Wenn Sie 'g() und f()' nicht in 'BBB' implementieren wollen, können Sie das nicht. Denn dann wird es abstrakte Klasse sein und Sie können keine 'BBB'-Instanzen haben. –

Verwandte Themen