Ein Kopierkonstruktor dient der Initialisierung eines Objektes mit dem Inhalt eines anderen - dem Erzeugen einer Kopie. Er wird aufgerufen, wenn bei der Definition eines Objektes ein anderes übergeben wird - sei es durch
klasse neuesObjekt (altesObjekt);
oder durch
klasse neuesObjekt = altesObjekt;
Der Zuweisungsoperator wird dagegen nur aufgerufen, wenn das Objekt schon vorher definiert ist:
klasse neuesObjekt; neuesObjekt = altesObjekt;
Oft reicht dazu die vom Compiler zur Verfügung gestellte Funktionalität, die zugehörigen Elemente zu kopieren, indem deren Kopierkonstruktoren aufgerufen werden. Es kann aber passieren, daß speziellere Operationen nötig sind, um Randbedingungen einzuhalten - z.B. um zusätzlichen Speicher zu reservieren oder um Zähler zu verändern. Z.B:
class CMeineKlasse { private: CMeineAndereKlasse* inhalt; public: CMeineKlasse() { inhalt = new CMeineAndereKlasse; } CMeineKlasse(CMeineKlasse& x) { inhalt = new CmeineAndereKlasse(*x.inhalt); // Objekt kopieren, auf das der Pointer zeigt } ~CMeineKlasse() { delete inhalt; } }
Ohne diesen Kopierkonstruktor würde nur der Pointer kopiert, nicht das Objekt, auf das dieser zeigt. Dies kann in gewissen Situationen erwünscht sein, häufig will man aber das Objekt kopieren, um es unabhängig verändern zu können und es zu behalten, wenn es anderswo gelöscht wurde. Folgendes Programmfragment würde ohne den selbstdefinierten Kopierkonstruktor Fehler produzieren:
void funktion() { CMeineKlasse* pObjektA; CMeineKlasse objektB = *pObjektA; //hier wird der Kopierkonstruktor aufgerufen delete pObjektA; // mit dem Destruktor wird auch der Speicher von pObjektA->inhalt freigegeben CMeineAndereKlasse temp; *objektB.inhalt = temp; // falls der Standard-Kopierkonstruktor genutzt worden wäre, wäre // mit dem Destruktor von pObjektA der Speicher für *pObjektA->inhalt // und somit auch der von *objektB.inhalt freigegeben worden - diese // Zuweisung wäre somit illegal. }