Operatoren überladen



  • Warum willst du die überhaupt nicht const haben? Macht doch nicht viel Sinn, die zu bearbeiten, dann hättest du nicht das normale verhalten von operator* oder erwartest du, dass wenn du schreibst: a = b*c, dass sich dann b oder c verändern? Nur so am Rande :p
    Ansonsten könntest du aber auch mal versuchen, die Funktion innerhalb der Klasse zu überladen oder ein Template mit explizierter Instanzierung zu nutzen, dann bräuchtest du nicht für jeden Typ die Funktion überladen und halt nur für die Klasse Bruch beispielweise das ganze explizit Instazieren.
    So, nu ein frohes neues Jahr *Party* 😉

    PS: Warum gibts keine Smiley mit Rakete oder so :p



  • class Foo
    {
       int i_;
    public:
       Foo (int i) : i_(i) {}
       int value () const { return i_; }
    };
    
    Foo operator + (Foo& r, Foo& l)
    {
       return r.value() + l.value();
    }
    
    int main ()
    {
       Foo x(2);
       Foo f = x + 3;
    }
    

    das funktioniert bei dir?

    @Ebi01:
    (vereinfacht gesagt) der grund dafür liegt an der konstruktion von einem temporären objekt, das nur an eine konstante referenz gebunden werden kann.



  • Ich denke ich würd das ca. so machen:

    class Bruch { 
    private: 
        int mz,mn; 
    public: 
        Bruch(int z=0, int n=1):mz(z), mn(n) {}
    
        int getZ() const { return mz; }
        int getN() const { return mn; }
        void display() const; 
    }; 
    
    ... 
    
    const Bruch operator *(const Bruch& b1,const Bruch& b2) { 
        Bruch erg(b1.getZ()*b2.getZ(), b1.getN()*b2.getN());
        return erg; 
    }
    


  • ist ja ganz nett, aber ich kann immer wieder nur mit dem antworten:
    http://tutorial.schornboeck.net/operatoren_ueberladung.htm



  • davie schrieb:

    class Foo
    {
       int i_;
    public:
       Foo (int i) : i_(i) {}
       int value () const { return i_; }
    };
    
    Foo operator + (Foo& r, Foo& l)
    {
       return r.value() + l.value();
    }
    
    int main ()
    {
       Foo x(2);
       Foo f = x + 3;
    }
    

    das funktioniert bei dir?

    @Ebi01:
    (vereinfacht gesagt) der grund dafür liegt an der konstruktion von einem temporären objekt, das nur an eine konstante referenz gebunden werden kann.

    @davie
    Nein, das nicht, aber das:

    class Foo
    {
       int i_;
    public:
       Foo (int i) : i_(i) {}
       int value () const { return i_; }
    };
    
    Foo operator + (Foo& r, Foo& l)
    {
       return r.value() + l.value();
    }
    
    int main ()
    {
       Foo x(2), y(4);
       Foo f = x + y;
    }
    

    Und nachdem das in allen Varianten funktioniert hat (übertragen auf Ebi01's Beispiel), hab ich irgendwie vergessen es noch mit Konstanten zu überprüfen [...]. Danke für deine Korrektur!

    @Ebi01
    Sorry für meinen vorigen Post bzw. meine Falschinformation, doch kein Compilerbug. 🙂 (Woher kam doch gleich der Spruch: "95% aller Fehler sitzen ca. 60 cm vor dem Bildschirm [...] )

    Caipi



  • abgesehen davon dass es mit nicht const referenzen ja nicht funktioniert, machen non const referenzen hier ja auch garkeinen sinn.

    sie sagen naemlich, dass der op* die brueche aendern darf - was ich persoenlich doch fuer komisch halte...



  • Vielen dank erst mal für die vielen Antworten. Ich gebe euch recht, daß bei dem Problem nicht const Referenzen wenig Sinn machen. Mir geht es halt vor allem darum zu begreifen was dahinter steckt.
    @Caipi

    @Ebi01:
    (vereinfacht gesagt) der grund dafür liegt an der konstruktion von einem temporären objekt, das nur an eine konstante referenz gebunden werden kann.

    kannst du mir da noch erklären weshalb das so ist? Ich glaub fast mir fehlt in dem Bereich das Hintergrundwissen.

    Danke schon mal

    Ebi



  • Ebi01 schrieb:

    kannst du mir da noch erklären weshalb das so ist? Ich glaub fast mir fehlt in dem Bereich das Hintergrundwissen.

    Wenn du einen Ctor hast, der nicht "explicit" ist, dann kann der Compiler diesen zum Unwandeln verwenden.

    Wenn wir nun eine Klasse Foo haben:

    class Foo
    {
    public:
      Foo(int){}
    };
    

    Dann kann der Compiler einen int in Foo umwandeln:

    void f(Foo){}
    
    f(2);
    

    Nur ist diese Umwandlung ein temporaeres Objekt. Denn es ist das selbe wie:

    f(Foo(2));
    

    Auf temporaere Objekte darf man keine non const Referenz haben. Deshalb kann f() das Foo hier nicht per Referenz sondern nur entweder by value oder by const reference nehmen.



  • (achtung, passt nur mehr bedingt dazu)

    Shade Of Mine schrieb:

    Auf temporaere Objekte darf man keine non const Referenz haben.

    was bei temporären objekten ganz lustig ist, da sie eigentlich nicht const sind.

    struct Foo
    {
       Foo (int) {}
       Foo& lvalue () { return *this; }
    };
    
    void bar (Foo &)
    {
    }
    
    int main ()
    {
       bar (Foo(2).lvalue());
    }
    

    zeigt wieder einmal die wunderbaren möglichkeiten, die dir c++ bietet [achtung]

    //edit: ärger ausschlafen, duschen und dann schreiben.



  • Danke vor allem an Shade of Mine. Das klingt für mich ziemlich plausibel. Jetzt nur nochmal ob ich das richtig verstanden hab. Da der Konstruktor nur ein temporäres Objekt anlegt und eigentlich auch sofort wieder zerstört würde es eine Referenz auf ein nicht mehr gültiges Objekt geben. Was passiert dann mit dem Objekt wenn const davor steht. Heißt das, daß es nicht sofort zerstört wird? 😕

    Ebi


Anmelden zum Antworten