Gute oder schlechte Lösung um den operator+ zu überladen?



  • Hi,

    ich lese grad den C++ Primer und hab im Rahmen einer Übung versucht, den operator+ für eine String-Klasse zu überladen, der zwei Strings miteinader verknüpft. Meine Lösung funktioniert (soweit ich das feststellen konnte), aber ich würde gerne wissen, wie diese Lösung einzuschätzen ist. Gibt es bessere Lösungen, und wenn ja, warum?

    String String::operator+ ( const String &rhs ) const
    {
      if ( !_size || !rhs._size )
      {
        if ( _size )
          return String ( *this );
        else
        {
          if ( rhs._size )
            return String( rhs );
          else
          {
            String str;
            return str;
          }
        }
      }
      else
      {
        char *c = new char[ _size+rhs._size ];
        int i,j;
        for ( i=0; i < _size; ++i )
          c[i] = _string[i];
        for ( j=0; j < rhs._size; ++j, ++i )
          c[i] = rhs._string[j];
        String str( c );
        delete[] c;
        return str;
        }
    }
    

    Danke, Jens



  • du brauchst doch eh den operator+= auch. vielleicht ist es besser, wenn du im operator+ den operator+= verwendest.

    ob die tests auf leere strings sinnvoll sind, muß man an realen beispielen ausmessen. ich hab das gefühl, daß kein mensch string a; a+=""; schreibt. auch nicht aus versehen und selten um die ecke. so selten, daß der test vermutlich mehr zeit kostst, als er bringen tut.



  • Auch wenns hier gerade nichts zur Sache tut möchte ich noch anmerken, dass solche Variablennamen wie "_foo" mit anführendem Unterstrich nicht gut sind (steht bestimmt auch in den FAQ wieso).



  • Hallo,

    danke für die schnellen Antworten. Die Überprüfung auf die leeren Strings hab ich deshalb reingenommen, da ja zwei String-Objekte miteinander verknüpft werden sollen. Für den Operator

    String String::operator+ ( const char *s )
    

    hätte ich diese Überprüfung tatsächlich weggelassen. Aber gut, darüber kann man wohl streiten. Was die Verwendung des (bislang nicht vorhandenen) operator+= angeht, ist das in etwa so gemeint:

    String String::operator+ ( const String &rhs )
    {
      String s( *this );
      s += rhs._string;
      return s;
    }
    

    @MaSTaH
    Das mit dem führenden Unterstrich hab ich aus dem Primer übernommen. Dort wurde das als gängige Praxis für die Bezeichnung von Membervariablen vorgestellt, um nicht mit denen der Methoden zu kollidieren. Beispielsweise:

    int size() { return _size; };
    

    Lasse mich aber gerne eines Besseren belehren, damit ich mir von Anfang an nichts Falsches/Schlechtes angewöhne (deshalb auch der Thread).

    Gruß, Jens



  • Weiteres steht hier: http://www.c-plusplus.net/forum/viewtopic.php?t=39461

    Bei dir ist zwar nicht sooo dramatisch, weil du einen kleinen Buchstaben danach hast, aber man sollte es imho trotzdem nicht machen. Zu dem Rest hat volkard ja schon fast alles gesagt.



  • D.A.U. schrieb:

    String String::operator+ ( const String &rhs )
    {
      String s( *this );
      s += rhs._string;
      return s;
    }
    

    genau.
    aber der op+ muß global werden!
    hast doch sicherlich nen konstruktor, der char* frisst?
    damit geht ja dann
    string h("hallo");
    string hw=h+"welt";
    aber nicht gehen tut
    string w("welt");
    stringt hw="hallo"+w;
    destawegen muß der op+ eigentlich aus der klasse raus. fall er dann auf members zugreifen muß, wird er friend. muß er aber wohl nicht weil wegen der op+=, der ja auch da ist.

    int size() { return _size; };
    

    kann mir nich passieren, weil meine methode getSize heißt.

    Lasse mich aber gerne eines Besseren belehren, damit ich mir von Anfang an nichts Falsches/Schlechtes angewöhne (deshalb auch der Thread).

    leider kannste nicht vermeiden, dir am anfang was schlechtes anzugewöhnen. in den ganzenm threads hier sind die meinungen ja gewöhnlich widersprüchlich und selten kommt mal in stilfragen ne einigung zu stande.

    wenn der op+= im op+ benutzt wird, ist der code ja so einfach... vielleicht sehen die tests dann ganz hübsch aus.

    string operator+(string const& a,string const& b){
       if(a.getSize()==0) return b;
       if(b.getSize()==0) return a;
       String result=a;
       result+=b;
       return result;
    }
    

    jetzt hab ich ganz vergessen, warum du so viel verschachtelt hattest.

    ich bin übrigens wieder von rhs und lhs abgekommen. hab es mir 95 angewöhnt und bestimmt bis 01 ganz viel benutzt, aber irgendwie isses doof. ch find a und b in operatoren die natürlicheren namen.



  • Danke erstmal. Wenn ich den operator+ global mache, muss ich doch, damit der von dir angesprochene Fall

    volkard schrieb:

    string w("welt");
    stringt hw="hallo"+w;

    (und natürlich auch andersrum) funktioniert, insgesamt drei Varianten anbieten, oder?

    String operator+( const String &a, const String &b );
    String operator+( const String &a, const char *b );
    String operator+( const char *a, const String &b );
    

    Vielen Dank!
    Gruß, Jens



  • D.A.U. schrieb:

    Danke erstmal. Wenn ich den operator+ global mache, muss ich doch, damit der von dir angesprochene Fall

    volkard schrieb:

    string w("welt");
    stringt hw="hallo"+w;

    (und natürlich auch andersrum) funktioniert, insgesamt drei Varianten anbieten, oder?

    String operator+( const String &a, const String &b );
    String operator+( const String &a, const char *b );
    String operator+( const char *a, const String &b );
    

    Vielen Dank!
    Gruß, Jens

    nee. durch den
    String::String(char const* str);
    wird im falle von
    String operator+( const String &a, const String &b );
    und
    stringt hw="hallo"+w;
    der op+ den linken parameter automatisch mittels des String::String(char const* str); in einen String konvertieren.
    oft läßt man also nur einen
    String operator+( const String &a, const String &b );
    stehen und bietet nicht alle drei an.
    alle drei anzubieten kann allerdings schnelleren code erzeugen, wenn oft auch mit char* hantiert wird. wird selten mit char* hantiert, sondern eher fast alles mit String gemacht, könnte das anbieten aller dre versionen den code vielleicht sogar verlangsamen, weil das programm größer wird? ka. jedenfals klappt die version mit nur einem op+ und ist auch recht üblich.



  • Interessant. Dann habe ich natürlich gleich noch eine Frage: In dem Beispiel aus dem Buch werden schon die Operatoren operator= und operator== überladen. Dafür ist aber in beiden Fällen jeweils eine Version mit dem Argument ( const String &rhs ) und eine mit dem Argument ( const char *c ) implementiert worden. Müsste da nicht auch die automatische Umwandlung über den "char"-Ctor die zweite Version überfüssig machen 😕 ?

    Gruß, Jens



  • D.A.U. schrieb:

    Interessant. Dann habe ich natürlich gleich noch eine Frage: In dem Beispiel aus dem Buch werden schon die Operatoren operator= und operator== überladen. Dafür ist aber in beiden Fällen jeweils eine Version mit dem Argument ( const String &rhs ) und eine mit dem Argument ( const char *c ) implementiert worden. Müsste da nicht auch die automatische Umwandlung über den "char"-Ctor die zweite Version überfüssig machen 😕 ?
    Gruß, Jens

    jo, müßte.
    bem op== würde ich aber trotzdem beide versionen leben lassen, weil es irgendwie sehr teuer klingt, string("hello hiudhfduiöhbö bfdi dfbifdölhbiö") mit "bdhslbhöufdsbhidösbhiöfdbiöbiöbhjidösbö" zu vergleichen, indem man zuerst das zeite argument in nen neuen string kopiert und dann vergleicht und dann schwupps, beim ersten zeichen schon feststellt, daß sie ungleich waren.
    aber funktionieren müßte auch die eine version alleine.


Anmelden zum Antworten