virtual public Vererbung



  • Hi,

    ich bin gerade mal auf so ein Fragment gestoßen

    class B : virtual public A .....
    

    und frage mich, was das soll (scheint ja gültiger Code zu sein).

    Wenn A eh schon eine virtuelle Klasse (eine Klasse mit virtuellen Methoden) ist, warum dann nochmal hinschreiben? Wenn sie keine ist, dann ändert sich doch kein Stück an A.

    Also kann das doch nur Auswirkungen auf B haben?? Nur was sollte das sein? Destruktor automatisch virtual? Würde keinen Sinn machen, da dann eh alle Basisklassen virtuell sein sollten (public Vererbung -> virtueller Destruktor nach Meyers). Dazu zwingt einen zwar keiner, aber schlechter Code ist das schon...

    Ist es also nur "informativ"? Oder veraltet? Ich bin verwirrt. 😕



  • Meinst du du bist der erste der dieses Konstrukt entdeckt hat? 😉



  • Sinnvoll bei mehrfachvererbung!

    Class Base
    Class GFrame:public Base
    Class BFrame:public Base
    Class MyFrame:public GFrame,public GFrame

    jetzt hätte MyFrame die public und protected member von Base doppelt, durch virtuelle vererbung passiert das nicht....



  • Wenn A eh schon eine virtuelle Klasse (eine Klasse mit virtuellen Methoden) ist

    Erster Denkfehler: eine Basis-Klasse mit virtuellen Methoden ist keine virtuelle Basisklasse. Eine virtuelle Basisklasse ist eine Klasse von der virtual geerbt wird.

    Der Unterschied zwischen virtueller- und normaler Vererbung: Normale Vererbung bedeutet Komposition-by-Value. Virtuelle Vererbung hingegen Komposition-by-Reference. Der Unterschied wird erst deutlich und relevant, wenn eine abgeleitete Klasse mehrmals die selbe Basisklasse hat:

    A
       / \
      B   C
       \ /
        D
    

    Bei normaler Vererbung enthält jedes D zwei A-Objekte. Eins über den Weg B-A und eins über den Weg C-A. Das ist nicht immer was man will und hier kommt virtuelle Vererbung ins Spiel. Lässt man B und C virtuell von A erben, so enthält D nur ein A-Objekt.
    Ein mögliches Objektlayout für D bei normaler Vererbung: D = ABAC
    Ein mögliches Objektlayout für D bei virtueller Vererbung: D = A*BA*CA

    Es gibt noch ein paar Feinheiten bei der virtuellen Vererbung (Konstruktion durch die am weitesten abgeleiete Klasse, Dominanzregel bei der Überschreibung...), aber der Hauptunterschied ist der den ich beschrieben habe.



  • Diamond-Shape... bääh... 😮

    Aber verständlich. Sind jetzt also alle, die von Base ableiten, dafür verantwortlich, virtual public abzuleiten?



  • Sind jetzt also alle, die von Base ableiten, dafür verantwortlich, virtual public abzuleiten?

    Richtig. Deshalb ist virtuelle Vererbung auch nicht transparent. Du musst vorher bereits wissen wie deine Hierarchie aussehen wird. Du kannst also nicht B und C normal von A ableiten und dann später ohne Änderung in D nur ein A Objekt haben. Das geht nur, wenn du die Vererbungsbeziehung zwischen B-A und C-A änderst.



  • // Oberste Basisklasse
    Class Base 
    {....};
    // 1. virtuell abgeleitete Klasse
    Class GFrame: virtual public Base 
    {....};
    // 2. virtuell abgeleitete Klasse
    Class BFrame: virtual public Base 
    {....};
    // Endgültige Klasse
    Class MyFrame: virtual public GFrame, public BFrame 
    {....};
    

    Klassendiagramm:

    Base
    virtual / \ virtual
    abgeleitet / \ abgeleitet
    / \
    GFrame BFrame
    \ /
    abgeleitet \ / abgeleitet
    \ /
    MyFrame

    so ok?



  • Klassendiagramm:

    Base 
    virtual     /  \ virtual 
    abgeleitet /    \ abgeleitet 
              /      \ 
            GFrame  BFrame 
              \      / 
    abgeleitet \    / abgeleitet 
                \  / 
               MyFrame
    

    so?


Anmelden zum Antworten