Wann wird Zuweisungsoperator aufgerufen und wann der Copy C'tor ?



  • Wenn ich nun von einem Programm ausgehe, das weder Syntax- noch Linker-Fehler aufweißt... hab ich dann nicht immer die "Großen Drei"?

    Nö.

    Üblicherweise verwendet man ein Hilfsmember oder eine Hilfsbasisklasse um die drei genannten Dinge zu unterdrücken.
    Beispiel:

    class NoCopyHelper
    {
    private:
        NoCopyHelper(NoCopyHelper const&) {} // darf ruhig definiert sein, stört nicht (muss aber nicht definiert sein, bringt auch nix)
    };
    
    class TrulyNonCopyable : private NoCopyHelper
    {
    //    NoCopyHelper m_dummy; // würde auch gehen
    };
    

    TrulyNonCopyable hat jetzt wirklich gar keinen Copy-Ctor mehr, nichtmal nen privaten.

    p.S.: für den Assignment-Operator reicht es schon wenn du ein "const" Member in der Klasse hast. Dann kann der auch nimmer implizit definiert werden.



  • Gugelmoser schrieb:

    inter2k3 schrieb:

    Das string-Objekt hält beispielsweise einen pointer auf einen Speicherbereich wo die Zeichenkette abgespeichert wird.
    Würdest du nun bitweise kopieren, würdest du einfach die Speicheradresse kopieren, nicht aber die verwaltete Zeichenkette. Ändert dann Objekt1 die Zeichenkette, würde Objekt2 ebenfalls etwas von der Änderung mitbekommen (zeigt ja auf den gleichen Speicherbereich) - oder Objekt1 wird gelöscht - was ist dann mit Objekt2?

    Gut du redest nun von deep-copy oder? deep-copy hat man aber sowieso nur, wenn man selbst explizit definiert. Das vom Compiler generierte macht nur eine flat-copy.

    Das ist schon klar - aber genau deshalb ist es ja wichtig, dass eben keine bitweise Kopie erstellt wird, sondern die Konstruktoren der member aufgerufen werden.

    Wenn deine eigene Klasse einen Zeiger auf Heapspeicher hält, dann musst du natürlich dafür sorgen, dass der Inhalt des Speichers auch kopiert wird.

    Wenn du allerdings wie beim obigen Beispiel einfach ein member hast, welches einen Zeiger auf Heapspeicher hat, dann wäre es jetzt schön doof wenn das member bitweise kopiert wird anstelle des Konstruktoraufrufs (der wäre ja dann für die Katz, aber gerade der würde für die deep-copy sorgen).



  • hustbaer schrieb:

    Üblicherweise verwendet man ein Hilfsmember oder eine Hilfsbasisklasse um die drei genannten Dinge zu unterdrücken.
    Beispiel:

    class NoCopyHelper
    {
    private:
        NoCopyHelper(NoCopyHelper const&) {} // darf ruhig definiert sein, stört nicht (muss aber nicht definiert sein, bringt auch nix)
    };
    
    class TruelyNonCopyable : private NoCopyHelper
    {
    //    NoCopyHelper m_dummy; // würde auch gehen
    };
    

    ah, ok :), aber kann man mit der Klasse TruelyNonCopyable jetzt noch etwas anfangen?

    lg



  • Freund Gugelmoser, hast du wirklich so wenig Phantasie?

    Viele meiner Klassen sind non-copyable. Denk an Fenster/Widgets, Files, Socket-Connections oder Mutexen.
    Bzw. auch Klassen für die es zwar eine naheliegende Kopiersemantik gibt, die aber eigentlich nie kopiert werden müssen, und wo der Copy-Ctor einigermassen aufwendig zu implementieren wäre.

    EDIT: scheissendreck, truly schreibt man ohne e! 😃


Anmelden zum Antworten