Variablen-Vererbung-Frage



  • da ist ein fehler im script!!?? letztes beispiel...
    http://tutorial.schornboeck.net/mehrfach_vererbung.htm

    class Derived : public Base1, public Base2
        {
        public:
          Derived(int a, int b)
          : Base1(a), Base2(b)
          {}
        };
    

    hier muss ja auch der konstruktor UltimateBase aufgerufen werden!!

    Derived(int a, int b)
          : UltimateBase(a), Base1(a), Base2(b)
          {}
    

    Bei einer 'normalen' Ableitung ruft der Konstruktor einer abgeleiteten Klassen nur die Konstruktoren seiner Basisklassen auf. Das trifft bei virtuell abgeleiteten Klassen aber nur dann zu, wenn die Basisklassen einen Standard-Konstruktor besitzen. Benötigt der Konstruktor der 'obersten' Basisklasse jedoch Parameter, so ist der Konstruktor der jeweils 'untersten' Klasse selbst dafür verantwortlich, den Konstruktor der 'obersten' Basisklasse aufzurufen...

    cu



  • nö shcon richtig alles
    es steht ja auch

    class Derived : public Base1, public Base2
    

    also wieso sollte Derived den ctor von der basisklasse von Base1 und von Base2 aufrufen ? UltimateBase() rufen schon die ctoren von Base1 und Base2 auf.

    Base1(int value) : UltimateBase(value)
          {}
    
    Base2(int value) : UltimateBase(value)
          {}
    


  • und warum meldet mein compiler (msvc7.1 bzw g++) dann:

    error C2512: 'UltimateBase::UltimateBase' : no appropriate default constructor available
    

    cu



  • vieleicht generiert der compiler nicht standardmäßig einen st-ctor 😕



  • Also es wurde ja genau das angesprochen dort was ich meinte. Jedoch ist da noch eine kleinigkeit.
    Wenn ich jetzt die Variable A in Ultimate habe, dann greife ich darauf zu, indem ich das über den namen der abgeleiteten klasse machen zu der sie gehört (wie im beispiel. Was ist aber wenn ich in einer der beiden abgeleieteten eine Variable habe die auch A heisst? Gäbe es nur die Basis und eine abgeleitete, könnte man das Problem mit doppelten namen so aus dem weg gehen, indem man den namen ebenfalls direkt aufruft. Wie jedoch wenn man das von der dritten abgeleiteten machen will? Schwer zu beschereiben, hier ein Bild:

    http://home.arcor.de/xdestroy/vererbung.JPG

    Das mit dem Fehler erhalte ich auch, verwende Visual.

    thx für eure Hilfe



  • Schmank schrieb:

    http://home.arcor.de/xdestroy/vererbung.JPG

    ist das nicht dieser 'diamond of death' oder wie das heisst?



  • Schmank schrieb:

    Also es wurde ja genau das angesprochen dort was ich meinte. Jedoch ist da noch eine kleinigkeit.
    Wenn ich jetzt die Variable A in Ultimate habe, dann greife ich darauf zu, indem ich das über den namen der abgeleiteten klasse machen zu der sie gehört (wie im beispiel. Was ist aber wenn ich in einer der beiden abgeleieteten eine Variable habe die auch A heisst? Gäbe es nur die Basis und eine abgeleitete, könnte man das Problem mit doppelten namen so aus dem weg gehen, indem man den namen ebenfalls direkt aufruft. Wie jedoch wenn man das von der dritten abgeleiteten machen will? Schwer zu beschereiben, hier ein Bild:

    http://home.arcor.de/xdestroy/vererbung.JPG

    Das mit dem Fehler erhalte ich auch, verwende Visual.

    thx für eure Hilfe

    Ein Beispiel:

    #include <iostream>
    
    struct Base {
        int A;
    };
    
    struct Mitte : virtual public Base {
        int A;
    };
    
    struct Mitte2 : virtual public Base {
        int A;
    };
    
    struct Derived : public Mitte, public Mitte2 {
        int A;
    };
    
    int main() {
        Derived obj;
        std::cout << &(obj.Mitte::A) << " " << &(obj.Mitte2::A) << " "
                  << &(obj.Base::A) << " " << &(obj.Derived::A) << std::endl;
    }
    

    Hier siehst du wie du alle Variablen ansprechen kannst. Es sind 4 unterschiedliche Adressen. Achte auf die virtuelle Vererbung, so dass es in Dervied auch nur ein Exemplar von Base::A hat, sonst gibts ne Fehlermeldung wegen Mehrdeutigkeit.



  • warum &(obj.Mitte::A)? reicht nicht einfach obj.Mitte::A??
    so hab ich das ja verstanden, aber wie schauts mit dem anderen fall aus (siehe bild). thx

    ps: das mit den virtuellen ableitungen wirft noch eine andere frage auf:
    wenn man Mitte1,2 virtuell abgeleitet hat von ultimate, und von mitte1,2 die derived hat, dann muss man ja von derived den konstruktor der basis-klasse aufrufen, wegen dem virtuellen... ok. aber was ist wenn ich von mitte1,2 den konstruktor von ultimate auch noch aufrufe. werden hier mitte 1,2 ignoriert?

    thx!!!

    ps: diamond of death? das hört sich gut an. könnte es sein, dass das ein allgemein ungelöstes problem ist?

    cu



  • Schmank schrieb:

    warum &(obj.Mitte::A)? reicht nicht einfach obj.Mitte::A??

    Weil ich die Adresse ausgebe und nicht den undefinierten Wert. 😉 (im Bsp-Code habe ich nichts zugewiesen)

    so hab ich das ja verstanden, aber wie schauts mit dem anderen fall aus (siehe bild). thx

    Das habe ich doch auch geklärt, oder??

    obj.Mitte1::A;
    

    Oder was meinst du?

    ps: das mit den virtuellen ableitungen wirft noch eine andere frage auf:
    wenn man Mitte1,2 virtuell abgeleitet hat von ultimate, und von mitte1,2 die derived hat, dann muss man ja von derived den konstruktor der basis-klasse aufrufen, wegen dem virtuellen... ok. aber was ist wenn ich von mitte1,2 den konstruktor von ultimate auch noch aufrufe. werden hier mitte 1,2 ignoriert?

    thx!!!

    Das nehme ich an. 🙂

    ps: diamond of death? das hört sich gut an. könnte es sein, dass das ein allgemein ungelöstes problem ist?

    cu

    .. 🙄



  • Schmank schrieb:

    ps: diamond of death? das hört sich gut an. könnte es sein, dass das ein allgemein ungelöstes problem ist?

    tritt bei mehrfachvererbung auf, guckst du: http://www.objectmentor.com/resources/articles/javacpp.pdf



  • Hmm. Wenn die ignoriert werden, gibt es eigentlich überhaupt nich nen Grund die Aufzuschreiben?? Oder werden die im Fall einer einzelnen Ableitung dann doch noch aufgerufen? (Also Falls man nur Ultimate, und eine der beiden Mitte-Klassen hat..).

    Wegen dem anderen: Ich meine, wenn ich die Ableitungen so mache (nicht virtual), habe ich ja die ultimate 2x. einmal in mitte1 und einmal in mitte2. hätte ich jetzt variablen mit unterschiedlichen namen könnte ich A in ultimate aufrufen wenn ich Mitte1::A (hier wird A in Ultimate über Mitte1 aufgerufen) oder Mitte2::A (hier wird das A von dem Ultimate von Mitte2 aufgerufen). Vorausgesetzt natürlich, das in Mitte1,2 keine Variablen mit dem Namen A vorhanden sind. Jetzt hammer ja das Problem, das die vorhanden sind...^^
    Meine erste Idee war, dass man schreibt Mitte1::Ultimate::A 😃 Aber das hat so, so meint mein compiler, also blödsinnig ergeben^^ 🙂

    thx! 🙂
    cu



  • @net: thx ich werd mir das mal durchlesen. Die sache wird immer intererssanter^^



  • Ich habe mir das auch mal durchgelesen. Das ist letztendlich dann ja auch der Grund, dass es in Java keine Mehrfachvererbung im eigentlichen Sinne gibt. Sinnvoll, denn das ist ist in der Tat ein Problem.


Anmelden zum Antworten