Assignment Operator & Copykonstruktor

Neben Standardkonstruktor und Destruktor, gehören auch Assignment Operator (=) und Copykonstruktor zu den automatisch generierten Methoden/Konstruktoren in C++ (Diese sind auch als „Great 4“ bekannt. Jede Klasse hat sie also per Default, und wenn es eigene Member in der Klasse gibt, so ist es sinnvoll sie zu implementieren:
MyClass(const MyClass& copy);
MyClass& operator=(const MyClass& copy);


Die Signatur ist für beide ähnlich, nur das die Überladung des Assignment Operators technisch eine Methode ist, während das andere ein Konstruktor ist. Eine Methode hat einen Rückgabewert, während ein Konstruktor immer nur für das erstellen und Initialisieren eines neuen Objektes zuständig ist. Auch kann der operator= mehrfach für verschiedene Typen überladen werden, so wäre auch ein MyClass& operator=(const My2ndClass& copy) denkbar.
Die Implementation erfolgt dann wieder in der .cpp Datei:
MyClass::MyClass(const MyClass& copy):m_dummy(copy.m_dummy)
{
}
MyClass& MyClass::operator=(const MyClass& copy)
{
    if(&copy == this)
        return *this;
    m_dummy = copy.m_dummy;
}


Für den Copykonstruktor können wir auch die Initialisierungsliste benutzen, der operator= ist schon etwas komplexer. Das if verhindert eine Selbstzuweisung, danach werden die Werte der übergebenen Instanz in die aktuelle Instanz kopiert. Wichtig ist hierbei auch, wenn die Klasse mit new allokierte Member besitzt, muss hier Speicher freigegeben werden, bevor die Kopie aus der copy Instanz erfolgt.

Deep vs. Shallowcopy

Wenn wir schon über das kopieren von Objekten reden, muss dies kurz erwähnt werden. Man kann ein Objekt tief oder flach kopieren. Was bedeutet dies? Dies bedeutet, dass der Programmierer einen Einfluss auf die Art wie ein Objekt kopiert wird hat.
Beim anfertigen einer Kopie kann man das gesamte Objekt kopieren, so dass man eine tiefe Kopie erhält. Dies heißt zum Beispiel für eine Stringklasse, das ihr internes char Array, welches sie dynamisch mit new anlegte, nun vollständig kopiert wird, es gibt also ein zweites, identisches char* Array im Speicher, gleichen Inhaltes. Eine tiefe Kopie verhindert, das Abhängigkeiten zwischen 2 oder mehr Instanzen einer Klasse entstehen. Kann aber den Nachteil haben, das sie unnötig viel Speicher verbrauchen. Eine flache Kopie würde hier nur den Pointer auf das im Heap liegende char Array kopieren. Nun entsteht das Problem, das man nicht wirklich weiß wann denn nun die letzte Instanz der Stringklasse das Array mit delete wieder freigeben darf. Hier würde zum Beispiel Referenzzählung helfen, wo eine Variable stets die Anzahl der aktuellen Instanzen kennt.