Operatorüberladung, Vererbung



  • Hey Leute,

    angenommen man hat für eine Klasse A den +Operator überladen

    const A operator+(const A& lhs, const A& rhs)
    {
     /* ... */ 
    }
    

    Angenommen B ist eine Unterklasse von A, müsste dann so etwas nicht möglich sein:

    B b1;
    B b2;
    
    B res = b1 + b2;
    

    Wobei hier das "+" verwendet werden sollte, welches man für die Oberklasse A definiert hat.

    Kompilieren tut das bei mir, aber ich bekomme unerwartet Werte 😞

    Gruß 🙂



  • Du hast fuer den B Teil der Klasse ja keinen operator+
    Da kann also nichts sinnvolles rauskommen.

    Als Merksatz: Niemals operatoren in polymorphen Klassen ueberladen.

    denn operatoren sagen, dass es eine Value-Klasse ist aber Polymorphie sagt, dass es keine Value-Klasse ist.



  • Ach Sorry, ich hab mich vertippt ...

    So ist der letzte Teil richtig:

    B b1;
    B b2;
    
    A res = b1 + b2;
    


  • Shade Of Mine schrieb:

    Als Merksatz: Niemals operatoren in polymorphen Klassen ueberladen.

    denn operatoren sagen, dass es eine Value-Klasse ist aber Polymorphie sagt, dass es keine Value-Klasse ist.

    CRTP 😉



  • Dumme Frage vllt, aber was ist eine Value-Klasse? 😞



  • @ Shade of Mine

    kannst du das mit Operatoren und Polymorphie näher erleutern? Oder vielleicht ein Beispiel machen?

    Vielen Dank!



  • MatheStein schrieb:

    Dumme Frage vllt, aber was ist eine Value-Klasse? 😞

    Klassen wie zB integer, vector, string, map,...
    Im Gegensatz zu Klassen wie zB command, observer, listener, ...

    Wenn du die Klasse mit einem Wert abbilden kannst (zB "hallo" fuer einen string) dann ist es eine Value Klasse. Die Trennung ist nicht immer 100% einfach und der Merksatz gilt in jeder Situation. Aber er ist eine gute Regel.

    PS:
    fuer Hyde++:

    Das Problem mit Operatoren wie zB + oder = ist folgendes: wir muessen vorher festlegen welcher Typ als Ergebnis rauskommt.

    Wenn wir die Klasse Base haben und davon eine Klasse ableiten: Derived - was passiert wenn wir Base+Derived rechnen? Kommt da ein Derived oder ein Base raus? Viel Schlimmer dabei ist aber noch: wir wissen ja nichtmal welche 2 Typen wir haben - die sind ja hinter der Polymorphie versteckt.

    Alles also ist nicht optimal, denn entweder wir fuellen den Teil von Derived der Base fehlt mit standardwerten oder wir ignorieren den Teil von Derived der in Base nicht vorhanden ist. Beides nicht so toll.

    Das ganze kann man natuerlich irgendwie loesen, aber idR ist es besser zu hinterfragen: warum haben wir diese Operatoren. idR geht es dabei um den operator= (da +, /, etc. meistens eh keinen Sinn machen).

    Und da haben wir folgendes Problem:
    Base& r = rand()%2 ? Base() : Derived();
    Base b = r;
    doofe Sache sowas. Was hat denn r? ein Base oder Derived? dh wir haben uU slicing hier.

    Meistens ist sowas viel entspannender mit einer clone() Methode zu loesen.



  • Danke für die Erklärung 👍


Anmelden zum Antworten