Kopierkonstruktor mit Vektoren oder Listen in den Attributen



  • Servus,

    ich habe noch keinen Kopierkonstruktor in C++ geschrieben, weiss aber aus der Java-Welt dass man dabei entscheiden muss, ob man deep oder shallow-copies will. Dazu lese ich in meinem schlauen C++-Buch (Breymann), dass dieser den Copy-Constructor mit Initialisierungslisten macht und dass der Compiler generell einen Standard-Kopierkonstruktor stellt.

    Ich fand es darauf hin angemessen hier einen Thread zu erstellen und nachzufragen auf was ich aufpassen muss, wenn ich der folgenden Klasse einen Kopierkonstruktor mitgeben will, sofern ich diesen brauche.

    Mein Ziel ist, dass ich die Werte der Listen, die in den Attributen stecke übernehme, nicht aber dass diese dann andernorts irrtümlicherweise noch änderbar sind ... in der Java-Welt würde ich sagen ich will dass mir alles als 'call by value' gegeben wird. Ist eigentlich mein Anliegen sogar das, was der Default-Copy-Constructor macht?

    Ich hoffe ich konnte mein Anliegen halbwegs verständlich rüberbringen.

    /**
     * Klasse, die ein multiples Sequenzalignment repräsentiert.
     */
    class Msa {
    
    private:
    
        /** Sequenzen des MSAs */
        seqan::StringSet< seqan::CharString > sequencesList;
    
        /** Namen der Sequenzen */
        seqan::StringSet< seqan::CharString > sequencesTagList;     
    
        /** Mastersequenz (Position 0) */
        seqan::CharString firstSequence;  
    
        /** Aminosäure-Symbole */
        std::vector<std::string> aminoAlphabet;  
    
        /** Aminoäuren-Paar-Symbole */
        std::vector<std::string> pairAminoAlphabet;  
    
        /** Relevanzangabe beim Filtern;  ein Eintrag pro Spalte, 0 = wichtig, 1 = unwichtig */
        std::vector<int> importantColumns;                
    
        /** MSA-Name */
        std::string name;                                              
    
    public:
    ...
    


  • Jay1980 schrieb:

    Servus,

    ich habe noch keinen Kopierkonstruktor in C++ geschrieben, weiss aber aus der Java-Welt dass man dabei entscheiden muss, ob man deep oder shallow-copies will.

    Ist hier keine Frage: Wir wollen immer deep copies.



  • std::vector und std::string haben eigene copy konstruktoren, die das schon für dich erledigen

    diesen seqan::StringSet kenne ich nicht, denke aber, dass auch dieser einen geeigneten kopierkonstruktor definiert hat



  • Okay, das heisst ich sollte tiefe Kopien anstreben und ich las, dass der Compiler beim Standardkonstruktor eine shallow-copy nimmt. Es muss also ein eigener her. Ich las auch dass man sich überlegen muss ob man die Dreierregel einhalten soll, wenn man einen eigenenKopierkonstruktor schreibt - okay dann bastle ich mal den constructor und melde mich dann wieder.

    http://de.wikipedia.org/wiki/Dreierregel_(C%2B%2B)



  • Jay1980 schrieb:

    Okay, das heisst ich sollte tiefe Kopien anstreben und ich las, dass der Compiler beim Standardkonstruktor eine shallow-copy nimmt. Es muss also ein eigener her. Ich las auch dass man sich überlegen muss ob man die Dreierregel einhalten soll, wenn man einen eigenenKopierkonstruktor schreibt - okay dann bastle ich mal den constructor und melde mich dann wieder.

    http://de.wikipedia.org/wiki/Dreierregel_(C%2B%2B)

    Die members der Klasse Msa machen bereits selber für sich tiefe Kopien.
    Deswegen mußt Du gar nix machen. Wenn Du nix machst, werden die Großen Drei von alleine angelegt, und zwar flach. Aber flach heißt hier flaches "Zuweisen" aller Attribute. Das "Zuweisen" der Atrribute macht jedes Attribut auf seine eigene Art. Natürlich tief!!! Dadurch ist, wenn Du nichst machst, von alleine alles tief. Außer, Du hast Zeiger als Attribute (oder noch ein paar verrückte Sachen wie file handles), dann mußt Du die Großen Drei selber bauen. Der vector zum Beispiel hat innendrin Zeiger. Deswegen haben die Autoren dem vector auch noch die Großen Drei implementiert. Ab jetzt kopiert er sich tief und ist normales C++. Wer in seiner Klasse vector benutzt, muß sich um die Zeiger im vecor nicht kümmern. Er kann flach vector this.v1=other.v1 sagen, in Wirklichkeit ist es tief, weil = bei uns normalerweise tief ist.

    (Falls seqan::StringSet normales C++ ist.)



  • Verstehe, ich mache nichts, das heisst ich mache 'flache Kopien', aber jeder meiner in den Attributen liegenden Typen hat für sich es so vereinbart, dass dieser eine tiefe Kopie anlegt?!

    Ist ja dann wie für mich geschaffen, wenn ich das richtig verstanden habe.



  • Jay1980 schrieb:

    Ist ja dann wie für mich geschaffen, wenn ich das richtig verstanden habe.

    In Wahrheit ist C++ nämlich viel einfacher als Java. Willkommen im Klub. 🙂


Log in to reply