Operatoren +, -, *, / durch +=, -=, *=, /= implementieren oder umgekehrt?



  • Hi!

    Angenommen ich habe eine Klasse, für die ich gerne sowohl +, -, *, / als auch +=, -=, *=, /= bereitstellen will.

    +=, -=, *= und /= packe ich in die Klasse rein, die anderen Operatoren mache ich global (so richtig?).

    Nun will ich ja nicht alles doppelt haben.
    Ich könnte es so machen:

    class Class
    {
        // ...
    
        Class& operator +=(const Class& rhs)
        {
            return *this = *this + rhs;
        }
    }
    
    const Class operator +(const Class& lhs, const Class& rhs)
    {
        // hier die eigentliche Arbeit machen
    }
    

    Oder umgekehrt:

    class Class
    {
        // ...
    
        Class& operator +=(const Class& rhs)
        {
            // hier die eigentliche Arbeit machen
        }
    }
    
    const Class operator +(const Class& lhs, const Class& rhs)
    {
        return Class(lhs) += rhs;
    }
    

    Welches davon ist besser?
    Was kann der Compiler besser optimieren?

    Danke!



  • Ein Vorteil der zweiten Variante, der mir gerade noch eingefallen ist:
    Da die eigentliche Rechnung in der Klasse gemacht wird, brauchen die globalen Operatoren nicht als friend deklariert zu werden, weil sie nicht auf die Attribute zugreifen müssen! 💡



  • Natürlich ist die zweite Variante die bessere und die Standardimplementierung, ein operator+ mus immer ein temporäres Objekt erstellen.



  • Aber das temporäre Objekt sollte doch heute jeder Compiler wegoptimieren können. Oder?



  • Die zweite Variante ist wohl aus den genannten Gründen die bessere. Ein weiterer Vorteil ist, dass man in diesem Fall auf boost.operators zurückgreifen kann. Also mit ..

    #include <boost/operators.hpp>
    
    class Class : public boost::addable< Class >
    {
    public:
        Class& operator+=( const Class& rhs )
        {
            // hier die eigentliche Arbeit machen
            return *this;
        }
    };
    

    .. wird der operator+( Class a, Class b ) automatisch generiert.

    Die Implementierung macht übrigens:

    Class operator+( Class lhs, const Class& rhs )
    {
        return lhs += rhs;
    }
    

    siehe dazu auch hier.

    Gruß
    Werner


Anmelden zum Antworten