Basisklassenfunktion von abgeleiteter Klasse aus aufrufen



  • Wie, und dann? Das ist der Funktionsaufruf für die Load-Funktion aus der Klasse A. Den schreibt man in die Funktion B::Load() hinein. Was da sonst noch in die Funktion B::Load() hineinkommt, mußte du schon selbst wissen. Ich kann schließlich nicht hellsehen.



  • lumpinus schrieb:

    A::Load() und dann?

    Nix mehr. Das war es schon. Wenn du in B::Load() A::Load() aufrufen willst, dann tust du das einfach mit A::Load().



  • Viel zu spät 😮



  • Mein Problem ist, dass B keine Instanz von A kennt.
    Wenn ich in B::Load(), Load() schreibe will ich, dass die Methode aus der Parent-Klasse (also A) aufgerufen wird, und nicht dass sich die Methode selbst aufruft.
    Wenn ich wollte, dass B::Load() sich selbst aufruft könnte ich ja auch explizit this->Load() schreiben.



  • Du bist in Klasse B, da führt der Aufruf "Load()" zur Load-Methode von Klasse B. Um dem Compiler zu sagen, daß du eine andere willst, mußt du das auch angeben - dazu verwendest du das "A::Load()".

    (und B kennt eine Instanz von A - sich selber ;))



  • lumpinus schrieb:

    Mein Problem ist, dass B keine Instanz von A kennt.

    Doch tut sie gaaaaaaanz sicher.B enthält ein anonymes Subobjekt vom Typ A.

    Gruß Spacelord



  • Ich glaube ich wisst überhaupt nicht was ich will.
    Deshalb Beispielcode:

    class A {
    public:
    	void Load();
    };
    
    class B : public A {
    public:
    	void Load();
    };
    
    void A::Load() {
    	//mach was
    }
    
    void B::Load() {
    	//mach was
    	/*
    	Jetzt will ich die Load() Methode aus A aufrufen
    	Wie geht das?
    	So wie es jetzt da steht wird ja wohl B::Load() aufgerufen,
    	d.h. die Methode ruft sich selbst auf
    	*/
    	Load(); 
    }
    


  • Wie dir schon mindestens zehnmal in diesem Thread geantwortet wurde:

    void B::Load() {
        //mach was
        A::Load(); 
    }
    

    (vielleicht solltest du mal versuchen, die ankommenden Antworten auch zu LESEN ;))



  • sag mal ehrlich, ließt du die antworten oder wartest du nur auf fertigen code?

    das wurde hier schon 10mal gesagt: A::Load()

    class A {
    public:
        void Load();
    };
    
    class B : public A {
    public:
        void Load();
    };
    
    void A::Load() {
        cout<<"A::Load";
    }
    
    void B::Load() {
        cout<<"B::Load";
        A::Load();
    }
    
    int main(int argc, char* argv[])
    {
     B test;
     test.Load();
     getch();       return 0;
    }
    

    [Edit] argh zu spät 😞



  • Das ist ja genial!! 💡

    Jetzt hab ichs verstanden, nur das Problem bleibt ja. Woher kennt B A ?



  • lumpinus schrieb:

    Das ist ja genial!! 💡

    Jetzt hab ichs verstanden, nur das Problem bleibt ja. Woher kennt B A ?

    ließ am besten nochmal in deinem buch oder einem guten tutorial nochmal aufmerksam das thema der vererbung durch!

    Wie schon erwähnt, es wurde sozusagen in B ein Subtyp der Klasse A erstellt! (einfacher kann ich es nicht erklären) 😞



  • Hallo

    lumpinus schrieb:

    Woher kennt B A ?

    B wird doch von A abgeleitet und daher kennt es auch die Funktionen von A.

    chrische



  • In Tutorials und Büchern steht, dass B::Load() A::Load() überschreibt und A::Load() damit für B gestorben ist. Der this Zeiger zeigt ja auf B nur welcher Zeiger zeigt auf A? Keiner, denn es gibt ja keine Instanz von A.



  • Der this Zeiger zeigt auf A. Denn ein B ist ein A. Ist das wirklich so schwer zu kappieren?



  • Doch: die Klasse B ist ja von A abgeleitet, deshalb gibt es irgendwo in ihrem Inneren noch einen A-Anteil - und dessen Elemente kannst du erreichen, indem du das A:: verwendest (auch wenn B sie überschrieben hat).



  • Ok, this zeigt auf A.
    ist mit this->Load() dann A oder B gemeint??

    Doch wohl B, sonst wäre das doch total sinnlos!!!



  • Ok,
    anscheinend komm ich nicht dahinter. Dann schreib ich jetzt eben statt A::Load A::LoadBasis.



  • lumpinus schrieb:

    Ok,
    anscheinend komm ich nicht dahinter. Dann schreib ich jetzt eben statt A::Load A::LoadBasis.

    Dein Load aus B überdeckt lediglich die Sichtbarkeit von dem Load aus A.
    Wenn du aber explizit angibst dass Load aus A benutzt werden soll wird auch diese Version genommen.
    Nichts anderes macht A::Load.
    Also was soll der Bullshit mit LoadBasis??
    Nur weil du es noch nicht verstanden hast?
    Es funktioniert doch mit A::Load,oder etwa nicht?Oder hast du es nach etwa 30 Posts noch nichtmal versucht?

    Gruß Spacelord



  • Hallo,

    du solltest dringend noch mal das Kapitel über Klassen und Vererbung lesen. Auch das Thema Sichtbarkeit von Namen solltest du dir nochmal anschauen.

    Mal ganz grob und kurz:

    Vererbung ist in der OOP eine "ist-ein"-Beziehung. D.h. ein Objekt einer abgeleiteten Klasse ist immer auch ein Objekt der Basisklasse. In C++ wird dies durch eine "Composition by value" erreicht. D.h. eine abgeleitete Klasse enthält immer auch alle Elemente seiner Basisklassen.

    Wenn du also eine Klasse B von einer Klasse A ableitest, dann sieht ein B-Objekt nachher (konzeptionell) so aus:

    |---------|
    | |-----| |
    | |  A  | |
    | |-----| |
    |    B    |
    |---------|
    

    In dem B ist als auch ein A-Objekt. Der A-Teil gehört fest zu B und kann in B ohne Probleme referenziert werden. Solange sich die Namen der Elemente von A und B unterscheiden, kannst du sie einfach mit ihrem Namen ansprechen. Sollten A und B allerdings Elemente gleichen Namens besitzen, so musst du sagen, welches Element du meinst. Das geht über den Scope-Resolution-Operator ::.

    struct A {
      int i;
    };
    
    struct B : A {
      int i;
      void f() {
        i = 2;      // i von B
        A::i = 2;   // i aus dem A-Teil von B
      }
    };
    

    Da ein B immer auch ein A ist, kannst du ein B z.B. auch über eine A-Referenz referenzieren:

    struct A {
      int i;
    };
    
    struct B : A {
      int i;
      void f() {
        this->i = 2;    // i von b
        // this ist vom Typ B* und jedes B 
        // ist immer auch ein A.
        // Nach der Zuweisung zeigt self auf den A-Teil von B
        A* self = this; 
        self->i = 2;    // i vom A-Teil von B
      }
    };
    

    Mit den Methoden verhält es sich ähnlich, nur das diese natürlich nicht pro Objekt existieren und mit dem Überladen und dem Überschreiben noch zwei Besonderheiten hinzukommen. Für diesen Thread wichtig: Jede abgeleitete Klasse kann alle (nicht privaten)-Methoden der Basisklasse verwenden. Auch hier gilt: sollte eine Methode der Basisklasse den selben Namen (besser: die selbe Signatur) haben, wie eine Methode der abgeleiteten Klasse, muss man in der abgeleiteten Klasse angeben, welche Methode man meint. Dazu verwendet man wiederum den Scope-Resolution-Operator (bei Namensgleichheit würde man besser auf eine using-Deklaration und damit Überladung vertrauen).

    Z2 schrieb:

    Der this Zeiger zeigt auf A. Denn ein B ist ein A. Ist das wirklich so schwer zu kappieren?

    Das stimmt nicht. Der this-Zeiger in diesem Fall auf das gesamte Objekt (also B). Wo sich der A-Teil in B befindet wird vom Standard nicht festgelegt, insofern ist nicht garantiert, dass die Adressen von B und dem A-Teil von B identisch sind - auch wenn das bei den meisten Compilern bei einfacher Vererbung der Fall sein dürfte.

    Ok, this zeigt auf A. ist mit this->Load() dann A oder B gemeint??

    Ohne die Deklaration von A::Load zu kennen, kann man diese Frage nicht beantworten. Kennst du bereits den Unterschied zwischen virtuellen und nicht-virtuellen Methoden und damit den Unterschied zwischen statischem und dynamischem Typ?



  • @HumeSikkins:
    Ich bin ja ganz begeistert von dem liebevoll arrangierten ASCII-Art Bildchen 😃 😉 .
    Wollen wir mal hoffen dass die gesamte Mühe nicht umsonst war(und irgendwie legen mir die letzten zig Posts dieses nahe).

    Gruß Spacelord


Anmelden zum Antworten