Vererbungsproblem



  • Hallo zusammen! 🙂
    Ich bin noch ziemlich neu in der C++-Welt und habe eine hoffentlich nicht zu dumme Frage zur Vererbung, die für mich unter Neuland fällt. Aber obwohl ich jetzt gefühlt tausende Beispiele dazu gewälzt habe, komme ich hier einfach nicht weiter. Vielleicht sehe ich mittlerweile auch nur den Wald vor lauter Bäumen nicht mehr.

    Ich habe eine Klasse A

    class A
    {
      Attribut m_1;
      Attribut m_2;   
    }
    

    Dann habe ich eine Klasse B, die von Klasse A erbt

    class B : A
    {   
        A::Attribut m_1;
        A::Attribut m_2;
        Attribut m_3;     
    }
    

    So weit kein Problem.

    Dann habe ich eine Menge Klassen C bis … n, die alle von B erben.

    class C : B
    {
               A::Attribut m_1;
               A::Attribut m_2;
               B::Attribut m_3;  
               Attribut m_4; 
    }
    

    Ob das Konstrukt guter Programmcode ist, kann ich nicht beurteilen. Es funktioniert bis jetzt jedenfalls reibungslos.

    Jetzt habe ich aber eine Stelle, an der ich partout nicht weiterkomme.

    Ich habe eine Instanz der Klasse B, nennen wir sie mal MyClassB.
    Und ich habe eine Instanz der Klasse C, nennen wir sie mal MyClassC.
    Sie sind von zwei unterschiedlichen Instanzen der Klasse A abgeleitet, also die Attribute m_1 und m_2 sind in myClassC und MyClassB nicht identisch.

    Jetzt möchte ich die Attribute m_1 und m_2, die MyClassC von "seinem" A geerbt hat, der Instanz MyClassB zuweisen und damit überschreiben, was B ursprünglich von "seinem" A geerbt hat.

    Ich kann das natürlich einzeln machen, also

    MyClassB.A::m_1 = MyClassC.A.::m_1;
    

    Das klappt zwar, hat aber den Nachteil, dass ich das für jedes einzelne Attribut bei jeder Klasse, die von B abgeleitet ist, erneut machen muss. Das sind ja einige, und es ist letztendlich immer dasselbe, da es ja dieselbe Basisklasse ist. Das ist vermutlich nicht die Lösung, wie man so etwas macht?

    Ich hatte die wahrscheinlich naive Erwartung, ich könnte einfach

    MyClassB.A = MyClassC.A
    

    schreiben. Aber hier streikt der Compiler, und der denkt sich vermutlich etwas dabei. 🙂

    Ich habe es mittlerweile mit einigen Mitteln und seit einigen Stunden erfolglos versucht, das zuzuweisen.
    Ich hoffe, ich habe keinen kolossalen Denkfehler bei der Vererbung. 😞
    Könnt ihr mir einen Tipp geben, was ich falsch mache?
    Schon mal vielen Dank!



  • Hört sich nach einem ziemlichen durcheinander bei dir an. Ich würde, wenn die Klassen sich sowieso ähneln, ein Interface implementieren und mit Polymorphie arbeiten. Vielleicht geht das was du vorhast, aber das könnte man eventuell auch anders lösen, in dem du dir noch mal Gedanken über deine Klasse machst. In einem Interface werden zB virtuelle Methoden benutzt die du dann überschreiben musst.

    Um das Problem zu lösen würde ich mir nochmal über deine Vererbung Gedanken machen. Hab hier mal gelesen, dass so eine wirre Vererbung nicht so gut sein soll. Hängt auch vielleicht davon ab was die Klassen machen sollen.



  • @Mirabella
    Ich gehe mal davon aus dass dein Beispielcode nicht dem Code entspricht den du wirklich hast, sondern Quatsch ist.
    Also dass die Zeilen
    A::Attribut m_1;
    A::Attribut m_2;
    etc. bloss beschreiben sollen dass es in B und C jeweils von A geerbte Member m_1 und m_2 gibt.

    In dem Fall würde ich sagen, was du suchst ist die Möglichkeit eine Zuweisung ala

    ASubObjectOfMyClassB = ASubObjectOfMyClassC; // "A" nicht im Sinne von "ein" sondern im Sinne von "class A"
    

    zu machen.

    Und das geht so:

    A& ASubObjectOfMyClassB = ClassB;
    A& ASubObjectOfMyClassC = ClassC;
    ASubObjectOfMyClassB = ASubObjectOfMyClassC;
    

    Tadaa.

    Dabei ist ASubObjectOfMyClassB einfach ein Verweis (eine Referenz) auf das geerbte A Subobjekt des Objekts ClassB , und ASubObjectOfMyClassC ein Verweis (eine Referenz) auf das geerbte A Subobjekt des Objekts ClassC .
    Da ASubObjectOfMyClassB bzw. ASubObjectOfMyClassC lediglich Referenzen auf A Objekte sind werden dabei auch nur die Member von A zugewiesen. Dass die beiden A Objekte in ein B bzw. C Objekt "eingebettet" sind spielt dabei keine Rolle.

    Das ganze kann man dann noch vereinfachen. ClassC ist ein C Objekt, und jedes C Objekt "ist" auch ein A Objekt, d.h. die Konvertierung in eine Referenz auf ein A Objekt ist implizit möglich. D.h. du kannst einfach schreiben

    A& ASubObjectOfMyClassB = ClassB;
    ASubObjectOfMyClassB = ClassC;
    

    Reicht.

    Bzw. man kann es sogar in einer Zeile schreiben:

    static_cast<A&>(ClassB) = ClassC;
    

    ps: Die Benamsung deiner Variablen ist sehr verwirrend. MyClassB ist ein Bezeichner den man eher mit einer Klasse assoziieren würde, du verwendest ihn aber für ein Objekt. Wenn schon mit "my", dann würde ich eher sowas wie MyBObject verwenden. Oder einfach nur MyB . Oder noch besser myB -- gleiches Benamsungsschema für Klassen und Objekte ist nämlich auch verwirrend. Oder auch gleich ganz ohne "my", dann vielleicht einfach someB .



  • @Bennisen
    Macht nicht den Eindruck als ob du die Frage verstanden hättest.
    Wieso beantwortest du sie dann?
    Das hilft doch niemandem 😕



  • @Mirabella
    Ich gehe mal davon aus dass dein Beispielcode nicht dem Code entspricht den du wirklich hast, sondern Quatsch ist.
    Also dass die Zeilen
    A::Attribut m_1;
    A::Attribut m_2;
    etc. bloss beschreiben sollen dass es in B und C jeweils von A geerbte Member m_1 und m_2 gibt.

    Ganz genau! Das hatte ich gedankenlos von meinen persönlichen Notizen übernommen, ich wollte mir damit selbst verdeutlichen, dass die Attribute vererbt und damit "auch da" sind.

    static_cast<A&>(ClassB) = ClassC;
    

    Vielen, vielen, vielen Dank! 👍 Das hat mein Problem schlagartig gelöst!!!! 🙂
    Da wäre ich echt niemals draufgekommen, ich merke, ich muss noch viel über C++ lernen. 🙂

    ps: Die Benamsung deiner Variablen ist sehr verwirrend. MyClassB ist ein Bezeichner den man eher mit einer Klasse assoziieren würde, du verwendest ihn aber für ein Objekt. Wenn schon mit "my", dann würde ich eher sowas wie MyBObject verwenden. Oder einfach nur MyB. Oder noch besser myB -- gleiches Benamsungsschema für Klassen und Objekte ist nämlich auch verwirrend. Oder auch gleich ganz ohne "my", dann vielleicht einfach someB.

    Sorry und danke für den Hinweis! Ich habe extra my... genommen, weil ich dachte, das wäre die gängige Konvention für Objekte. 🙂 Ich mag das selbst nicht wirklich. someB habe ich noch nie gesehen, gefällt mir aber wesentlich besser.



  • Bitte bitte 🙂

    BTW: Mir fällt auf dass ich das "My" in "MyClassX" unterschlagen habe, und statt dessen nur "ClassX" geschrieben. Das war keine Absicht. Hoffe es war nicht verwirrend.


Anmelden zum Antworten