Kopierkonstruktoren und operatoren / abgeleitete Klasse


  • Administrator

    Grüsse zusammen,

    Ich habe in meinen letzten Thread dank netter Hilfe nun herausgefunden, wie man den Basis Operator = aufruft und nicht immer alle Member neu zu kopieren.
    Um alles zusammenzufassen und damit es vielleicht jemand dann über die Suche besser findet, es ging um folgendes:
    Ich definiere einen operator = in einer Basisklasse. Leite eine Klasse von der Basisklasse ab und definiere in der neuen Klasse wieder den operator =. Um nicht alle Member neu zu setzen, kann man den Basis::operator = aufrufen.

    CDerived : public CBase
    {
        CDerived& operator =(const CDerived& d)
        {
            CBase::operator =(d);
    
            // Die Member der Klasse CDerived.
    
            return *this;
        };
    }
    

    Nun jetzt möchte ich das Thema ein wenig erweitern. Zum einen wie löst man dies in einem Kopierkonstrutkor? Ich habe in dem Kopierkonstruktor der abgeleiteten Klasse nun einfach folgendes gemacht:

    CDerived : public CBase
    {
        CDerived(const CDerived& d)
        {
            CBase::operator =(d);
    
            // Die Member der Klasse CDerived.
        };
    }
    

    Was auch prima funktioniert, doch ob das so korrekt ist, ist meine Frage?

    Desweiteren frage ich mich auch, wie ich dies bei anderen operatoren machen soll, wie zum Beispiel die Vergleichsoperatoren. Vielleicht so:

    CDerived : public CBase
    {
        bool operator ==(const CDerived& d)
        {
            return CBase::operator ==(d) /* && Die Member der Klasse Dervied */;
        };
    }
    

    Danke nochmals an CStoll, für die Hilfe im anderen Thread.
    Und danke für die Hilfe im voraus in diesem Thread (von wem auch immer).

    Grüssli



  • Dravere schrieb:

    Zum einen wie löst man dies in einem Kopierkonstrutkor?

    CDerived : public CBase
    {
        CDerived(const CDerived& d) : CBase(d)
        {
            // Die Member der Klasse CDerived.
        };
    }
    

    Also einfach den Kopier-Konstruktor der Basisklasse aufrufen. 🙂

    [/quote]

    Auch der Ansatz für die Operatoren sieht eigentlich ganz vernünftig aus.

    Vielleicht auch ein

    if(!CBase::operator==(other)) return false;
    // Rest vergleichen
    

    Je nach Umfang der noch zu vergleichenden Variablen.



  • Für den Konstruktor gibt es eine Initialisierungsliste:

    Derived(const Derived& val) : Base(val)
    {
      //Derived-eigene Member kopieren
    }
    

    Bei anderen Operatoren (wie ==) dürfte es auch so funktionieren - allerdings solltest du eventuell noch die eigenen Member deiner Klasse kontrollieren.
    (wenn der op== so wie da unten wirklich ausreicht, kannst du ihn auch weglassen)


  • Administrator

    CStoll schrieb:

    ... allerdings solltest du eventuell noch die eigenen Member deiner Klasse kontrollieren.
    (wenn der op== so wie da unten wirklich ausreicht, kannst du ihn auch weglassen)

    Deswegen habe ich ja noch im Kommentar den Logical And dazugefügt. Aber wollte nicht noch irgendwelche Memberattribute deklarieren und sie dann vergleichen (war zu faul, das alle noch aufzuschreiben ^^) ...

    Aber ich hätte noch eine Verständnis Frage, ganz allgemein zu den Operatoren. Normalerweise in einer normalen Funktion übergibt man etwas und erhält was zurück. Beim operator mit == funktioniert dies ja anscheinend auch genau so. Doch beim operator = versteh ich es nicht so recht. Man gibt ja in der Basis ein Objekt (bzw. ein dereferenzierten Zeiger) zurück, aber fängt das im Derived gar nicht auf und trotzdem ist wird es korrekt übernommen.
    Zudem was ist eigentlich dieses this? Also normalerweise ist es ja ein Zeiger auf die aktuell Klasse. Aber wir rufen ja der Operator per scope resolution auf und nicht von einer Variable aus. Dann müsste das doch eigentlich gar nicht funktionieren.
    Bzw. wieso können wir den operator per Scope resolution aufrufen? Normalerweise geht das ja nur bei static funktionen. Also was macht dieses operator keyword genau? ^^

    Sorry wenn ich hier so Grundbasisfragen frage, aber habe mir bisher alles per Bücher und Tutorials selber beigebracht und nie eine Möglichkeit gehab nachzufragen. Bei der MFC habe ich es inzwischen ein paar Foren weiter oben schon lange ausgenutzt, aber jetzt möchte ich auch meine Durst nach dem absoluten Grundwissen noch völlig stillen und nicht einfach ein paar Dinge hinnehmen und denken es ist halt so 😉

    Danke wieder mal im voraus und danke für die bisherige Hilfe.

    Grüssli



  • Wenn deine eigene Klasse sich an die üblichen Konventionen hält, gibt op= das Objekt zurück, an das du etwas zugewiesen hast* (genau das macht der "return *this;" am Ende - this ist ein Pointer auf das aktive Objekt).
    Für die Implementierung des Derived::op= benötigst du diesen Rückgabewert nicht weiter, sondern kannst dich gleich darum kümmern, deine eigenen Datenwerte zuzuweisen.

    Bzw. wieso können wir den operator per Scope resolution aufrufen? Normalerweise geht das ja nur bei static funktionen.

    Das geht auch innerhalb der Klasse, um direkt auf eine Methode der Basisklasse zuzugreifen (übrigens nicht nur bei Operatoren, sondern bei jeder Memberfunktion).

    Also was macht dieses operator keyword genau? ^^

    "operator=" etc ist eine ganz normale Memberfunktion deiner Klasse und kann auch direkt aufgerufen werden. Die Besonderheit ist halt, daß diese Methoden auch für die Auswertung von Operatoren genutzt werden.

    * Auf diese Weise lassen sich Zuweisungsketten ala "x=y=1;" umsetzen.


  • Administrator

    Ok, vielen dank, jetzt glaub ich, habe ich es endgültig geschnallt.
    Wenn ich mal wieder was habe komme ich wieder und hoffe CStoll ist dann immer noch anwesend *g*

    Grüssli


Anmelden zum Antworten