richtig Copy-Konstruktor schreiben



  • Hi,

    eine Klasse hat ein Attribut

    char* str;
    

    Wie würde man dafür einen Copy-Konstruktor schreiben?

    so??

    T(const& T t)
    {
        str = new char[32];
        strcpy(str, t.str);
    }
    


  • Wenn deine Klasse T ist sieht der Copy C'tor so aus:

    T( const T& other )
    {
      // ...
    }
    

    Beim kopieren musst du darauf achten das keine Memoryleaks entstehen (bei Exceptions oder Selbstzuweisung).

    Eine Idee die Selbstzuweisung zu unterbinden ist folgende:

    T( const T& other )
    {
      if ( this == &other )
        return;
    
      // ...
    }
    

    Andererseits kann man sich diese Abfrage auch sparen:

    T( const T& other )
    {
      char* tmp = str;
      str = new char[ 32 ];
      strcpy( str, other.str );
      delete [] tmp; // speicher freigeben ist wichtig
    }
    

    Wobei du darauf achten solltest das str gültig oder NULL ist. Außerdem solltest du evtl die Länge des Strings von "other" berücksichtigen.

    Und um sich den ganzen ärger zu sparen könntest du einfach std::string verwenden statt char*.

    grüße



  • David_pb schrieb:

    Eine Idee die Selbstzuweisung zu unterbinden ist folgende:

    T( const T& other )
    {
      if ( this == &other )
        return;
    
      // ...
    }
    

    Zuweisung ist was anderes als Kopie. Eine Selbstkopie gibt es nicht, so ein Test ist überflüssig.

    @sly: Die Frage ist im Allgemeinen nicht zu beantworten, da du nicht schreibst, welche Assoziation zwischen str und deiner Klasse besteht. Nehmen wir mal an, dass die Klasse str besitzt. Dann ist dein Ansatz schon fast gut, allerdings solltest du dafür sorgen, dass dein String auch in den allozierten Speicher reinpasst. Pauschal 32 ist irgendwann zu wenig und ein potentielles Sicherheitsleck.



  • Bashar schrieb:

    David_pb schrieb:

    Eine Idee die Selbstzuweisung zu unterbinden ist folgende:

    T( const T& other )
    {
      if ( this == &other )
        return;
    
      // ...
    }
    

    Zuweisung ist was anderes als Kopie. Eine Selbstkopie gibt es nicht, so ein Test ist überflüssig.

    @sly: Die Frage ist im Allgemeinen nicht zu beantworten, da du nicht schreibst, welche Assoziation zwischen str und deiner Klasse besteht. Nehmen wir mal an, dass die Klasse str besitzt. Dann ist dein Ansatz schon fast gut, allerdings solltest du dafür sorgen, dass dein String auch in den allozierten Speicher reinpasst. Pauschal 32 ist irgendwann zu wenig und ein potentielles Sicherheitsleck.

    Arg, hast natürlich recht... 😮 Hm, is das spät heute! :-))



  • Nach Möglichkeiten sollte man die Resourcen-Belegung/Freigabe in einzelne Klassen aufteilen. Das erleichtert die Exception-Sicherheit um einiges.

    Für Strings gibt es (wie schon gesagt wurde) zB std::string



  • [quote]Nehmen wir mal an, dass die Klasse str besitzt.[/qoute]
    Das ist der Fall.

    Dann ist dein Ansatz schon fast gut, allerdings solltest du dafür sorgen, dass dein String auch in den allozierten Speicher reinpasst. Pauschal 32 ist irgendwann zu wenig und ein potentielles Sicherheitsleck.

    das stimmt.

    Wäre es so besser?

    T(const& T other)
    {
        str = new char[strlen(other.str) + 1];
        strcpy(str, t.str);
    }
    

    Und um sich den ganzen ärger zu sparen könntest du einfach std::string verwenden statt char*.

    Das würde ich auch gerne, allerdings verbietet mir die Vorgabe mit STL zu arbeiten. ( -> low level Programmierung).



  • Ja, das könnte man so nehmen (eventuell müsstest du noch abfangen, daß other.str nicht NULL werden darf). Dazu benötigst du jetzt noch einen Zuweisungs-Operator (dort wird dann David's "Schutz vor Selbstzuweisung" wichtig) und einen Destruktor, der den Speicher freigibt.


Anmelden zum Antworten