String x = (String) tchar; casting operator overloading...



  • TCHAR* foo = whatever;
    
    String s = foo;  // Konstruktor erzeugt String aus foo
    s = foo;         // Zuweiungsoperator führt nötige Aufräumarbeiten aus und erzeugt
                     // neuen String aus foo
    

    Was soll hier trügerisch sein?



  • Deine sollte folgendes beinhalten

    class String{
    public:
      String();
      String(const String&);
      String(const TCHAR*);
    
      String&operator=(const String&);
      String&operator=(const TCHAR*);
    
      const TCHAR*c_str()const;
      //THCAR*c_str(); keine gute Idee da das ja alle Probleme eines TCHAR[] hat
    
      //operator TCHAR*(); keine gute Idee zur Begründung sieh mein letzter Post
    
      ~String();
    };
    

    String(const TCHAR*arg) sollte arg auf keinen Fall deleten! Sonst wird das zum Problem:

    String str(L"Hello");//Bum L"Hello" liegt nicht im Heap
    

    Ansonten noch ein kleiner Tip. Im op= sollte new immer vor delete aufgerufen werden. Also:

    TCHAR*new_buffer=new TCHAR[...];
    delete[]buffer;
    buffer=new_buffer;
    

    Wenn du es andersrum machst und new wirft eine Exception ist dein String irreparabel futsch, so ist nur die Zuweisung gescheitert.

    Und beachte, dass beim delete ein [] steht. Bei manchen Compilern kann es bum machen wenn der nicht da ist.



  • TCHAR* foo = whatever;
    
    String s = foo;  // Konstruktor erzeugt String aus foo
    s = foo;         // Alter String wird zerstört. Konstruktor legt durch implizite Typumwandlung einen neuen String an.
    

    So ist es richtig. Immer vorrausgesetzt, es gibt keinen Zuweisungsoperator. Das ist richtiger und gültiger Code.

    Stell Dir vor, deine Stringklasse speichert nicht nur den String sondern noch andere x-beliebige Informationen, die irgendwie mit der Klasse zusammenhängen. Diese gehen bei so einem Aufruf mal eben verloren. Da man aus dieser Schreibweise nicht offensichtlich erkennen kann, was da nun eigenltich aufgerufen wird, ist es so gefährlich.



  • 7H3 N4C3R schrieb:

    Stell Dir vor, deine Stringklasse speichert nicht nur den String sondern noch andere x-beliebige Informationen, die irgendwie mit der Klasse zusammenhängen. Diese gehen bei so einem Aufruf mal eben verloren. Da man aus dieser Schreibweise nicht offensichtlich erkennen kann, was da nun eigenltich aufgerufen wird, ist es so gefährlich.

    Eine Stringklasse ist keine Stringklasse wenn sie mehr tut als eine Stringklasse tut! Also muss der Ctor sämtliche Informationen vom TCHAR* herleiten können.

    Das einzige was mich an dem Code stört ist, dass der op= ja die op=s aller Member aufruft. Und beim Pointer auf den Buffer wird da ein delete nicht aufgerufen => Speicherloch.



  • 7H3 N4C3R schrieb:

    Stell Dir vor, deine Stringklasse speichert nicht nur den String sondern noch andere x-beliebige Informationen, die irgendwie mit der Klasse zusammenhängen. Diese gehen bei so einem Aufruf mal eben verloren. Da man aus dieser Schreibweise nicht offensichtlich erkennen kann, was da nun eigenltich aufgerufen wird, ist es so gefährlich.

    Eine Stringklasse ist keine Stringklasse wenn sie mehr tut als eine Stringklasse tut! Also muss der Ctor sämtliche Informationen vom TCHAR* herleiten können.

    Das einzige was mich an dem Code stört ist, dass der default op= ja die op=s aller Member aufruft. Und beim Pointer auf den Buffer wird da ein delete nicht aufgerufen => Speicherloch.



  • 7H3 N4C3R schrieb:

    TCHAR* foo = whatever;
    
    String s = foo;  // Konstruktor erzeugt String aus foo
    s = foo;         // Alter String wird zerstört. Konstruktor legt durch implizite Typumwandlung einen neuen String an.
    

    So ist es richtig. Immer vorrausgesetzt, es gibt keinen Zuweisungsoperator. Das ist richtiger und gültiger Code.

    Stell Dir vor, deine Stringklasse speichert nicht nur den String sondern noch andere x-beliebige Informationen, die irgendwie mit der Klasse zusammenhängen. Diese gehen bei so einem Aufruf mal eben verloren. Da man aus dieser Schreibweise nicht offensichtlich erkennen kann, was da nun eigenltich aufgerufen wird, ist es so gefährlich.

    Ich weiß nach wie vor nicht was du meinst. Erstens macht die Zeile "s = foo" Gebrauch von einem Zuweisungsoperator und 2. kann deine Stringklasse Millionen von weiteren Infos haben - alles kein Problem wenn man operator= entsprechend überlädt.



  • Erstens macht die Zeile "s = foo" Gebrauch von einem Zuweisungsoperator

    Wenn man einen definiert hat. Wenn nicht, und es gibt einen Konstruktor, der den Datentyp annehmen kann, so wird dieser ausgeführt. Probier es aus.



  • 7H3 N4C3R schrieb:

    Erstens macht die Zeile "s = foo" Gebrauch von einem Zuweisungsoperator

    Wenn man einen definiert hat. Wenn nicht, und es gibt einen Konstruktor, der den Datentyp annehmen kann, so wird dieser ausgeführt. Probier es aus.

    Na davon bin ich ja ausgegangen, sonst ist die Klasse sowieso Schrott.



  • 7H3 N4C3R schrieb:

    Erstens macht die Zeile "s = foo" Gebrauch von einem Zuweisungsoperator

    Wenn man einen definiert hat. Wenn nicht, und es gibt einen Konstruktor, der den Datentyp annehmen kann, so wird dieser ausgeführt. Probier es aus.

    ganz so einfach ist es auch nicht.

    String s = "foo";
    

    das ruft dir garantiert den konstruktor auf (wenn es einen passenden gibt)

    String s;
    s = "foo";
    

    das ruft entweder den passenden zuweisungsoperator auf oder - falls es den nicht gibt - konstruiert aus "foo" ein temporäres objekt und weist das dann über den zuweisungsoperator "String &operator = (const String &)" (der übrigens implizit generiert wird) letztendlich an s zu.

    also: den normalwerweise implizit generierten zuweisungsoperator undefiniert lassen (bringt natürlich eine gewisse einschränkung), bzw. ihn als String &operator = (String &) deklarieren, oder den konstruktor explicit machen, oder einen eigenen passenden zuweisungsoperator definieren, der diese hässliche implizite umwandlung unterdrückt.



  • Stimmt, an den automatisch generierten Zuweisungsoperator hatte ich garnicht mehr gedacht 🙂


Anmelden zum Antworten