Es gibt das ungeschriebene Gesetz der großen Drei. Die großen Drei sind Kopierkonstruktor, Zuweisungsoperator und Destruktor. Diese 3 werden vom Compiler generiert wenn wir sie nicht selber schreiben. Die Regel besagt: sobald wir einen dieser 3 schreiben müssen wir die anderen Beiden auch schreiben.
Denn man muss nur dann einen Kopierkonstruktor schreiben, wenn der Compilergenerierte nicht reicht. In diesem Fall wird aber auch der Compilergenerierte Destruktor und Zuweisungsoperator auch nicht reichen.
Nehmen wir als kleines Beispiel Klasse für dynamische Arrays:
#include <algorithm> //für swap
using namespace std;
class Array
{
private:
unsigned length; //keine negative Länge
int* value;
void copy(int* value, unsigned length)
{
for(unsigned i=0; i<length; ++i)
{
this->value[i]=value[i];
//this-> weil der Parameter value verdeckt this->value
//mittels this-> sagen wir dem Compiler welches value wir wollen
}
}
public:
Array(int* value, unsigned length)
: length(length), value(new int[length])
{
copy(value, length);
}
Array(Array const& other)
: length(other.length), value(new int[other.length])
{
copy(other.value, other.length);
}
Array const& operator=(Array const& other)
{
Array temp(other); //benutze CopyCtor um eine Kopie zu erstellen
swap(temp); //tausche Member mit der Kopie aus
return *this;
} //Kopie wird zerstört
~Array()
{
delete [] value;
}
void swap(Array& other)
{
swap(value, other.value);
swap(length, other.length);
//swap funktioniert wie unser tausche - allerdings für jeden Variablentyp
}
};
Diese Klasse ist natürlich noch nicht fertig, aber der Sinn der Regel der großen Drei ist erkennbar. Da wir dynamischen Speicher verwenden müssen wir diesen immer selbst kopieren - der Compiler würde sonst einfach nur den Zeiger kopieren: arr1=arr2; Hier würden arr1 und arr2 auf den selben Speicher zeigen und der Speicher auf den arr1 gezeigt hat, wäre verloren.