Warum Operator global deklarieren?



  • Dieser Beitrag wurde gelöscht!


  • Sind die Operatoren "lokal" als Member-Funktion implementiert, so ist der Ausdruck lhs + rhs äquivalent zu lhs.operator+(rhs). Das bedeutet dass die der linke Operand nur von einem Klassen-Typ sein kann, welcher einen operator+()-Member hat.

    Bei c_str_1 + std_str_2 ist der linke Operand allerdings keine Instanz eines Klassen-Typs, sondern ein char[80]-Array. Dieses kann aber als nicht-Klassen-Typ keine Member-Funktionen haben, weshalb sich auch kein "lokaler" operator+() definieren lässt, der bei c_str_1 + std_str_2greift.

    Die Lösung ist, den operator+() als freie Funktion zu implementieren, da hier der linke Operand einen beliebigen Typen haben kann und nicht automatisch den Typen der Klasse haben muss, zu welcher der operator+() gehört.

    Es empfiehlt sich sogar, solche Operatoren generell als freie Funktionen zu implementieren. Das hat nämlich u.a. den Vorteil, dass man diese Operatoren an einer zentralen Stelle im Code implementieren kann und sich z.B. so eine Additions-Operation nicht auf mehrere Klassen (und damit wahrscheinlich mehrere Quellcode-Dateien) verteilt, je nachdem ob man einen Operanden von rechts oder von links addiert.

    Das gilt im Besonderen, wenn die Operation kommutativ ist und der Code, der a + b und b + a berechnet, derselbe ist. Bei einem String ist das zwar nicht der Fall, aber für andere Klassen würde ein solcher Member-Operator möglicherweise unnötig redundanten Code erfordern.



  • Vielen Dank, für die Beantwortung meiner Frage. Dann haette ich davon ausgehend noch eine zweite
    und zwar bei diesem Code

    
    class MyString{
    
    public:
    
        static std::size_t const max_length = 1024;
    
    
        MyString();
    
        MyString(MyString const& string);
    
        MyString(char const*     c_string);
    
    
        MyString& operator=(MyString const& string);
    
        MyString& operator=(char const*     c_string);
    
        MyString& operator+=(MyString const& string);
    
        MyString& operator+=(char const*     c_string);
    
    
        char const& operator[](std::size_t index)const;
    
        char&       operator[](std::size_t index);
    
    
        std::size_t length()const{ return length_; }
    
    
    private:
    
        char        data_[max_length];
    
        std::size_t length_;
    
    
        void selfcopy(MyString const& string);
    
        void selfcopy(char const*     c_string);
    
    };
    
    
    MyString operator+(MyString const& lhs, MyString const& rhs);
    
    MyString operator+(MyString const& lhs, char const rhs[]);
    
    MyString operator+(char const lhs[],    MyString const& rhs);
    

    frage ich mich, warum manche eine Referenz wie MyString& und manche ein Objekt wie MyString zurückgeben.
    Warum gibt man da nicht das komplette Objekt zurück, dass dürfte doch gar keinen Unterschied machen, oder nicht?
    Bzw. warum gibt man bei dem einen ein komplettes Objekt und bei dem anderen nur eine Referenz zurück?



  • Bei Operatoren wie '=' oder '+=' wird (üblicherweise) eine Referenz zurückgegeben, das ja das Objekt selbst intern verändert wird, während bei '+' oder '-' intern ein neues Objekt erzeugt wird (also wird dieses Objekt als Kopie bzw. mittels RVO zurückgegeben).



  • Achje, das wurde dir doch schon hier beantwortet: https://www.c-plusplus.net/forum/topic/348719/frage-zu-operatoren-und-deren-rückgabewerten/11

    Folgender Code

    int i;
    (i = 5) = 23;
    std::cout << i << std::endl;
    
    i = 0;
    
    (i += 5) = 23;
    std::cout << i << std::endl;
    

    baut als C++ fehlerfrei und es kommt 2x 23 raus. Wenn man möchte dass eigene Klassen sich ähnlich verhalten, muss man eine Referenz zurückgeben. Mit zurückgeben von Kopien würde der Code nicht bauen, und wenn man ihn dann zum Bauen überredet würde nicht mehr 2x 32 rauskommen sondern 2x 5.


Anmelden zum Antworten