11 Stimmen

Sollten wir explizit einen Kopierkonstruktor schreiben, wenn das Klassenmitglied ein Vektor ist?

struct myType {
    vector<char*> ls;
};

Hier ls hält Zeiger auf char . Wenn ein benutzerdefinierter Kopierkonstruktor für myType nicht vorgesehen ist, wird myType Der Standard-Kopierkonstruktor führt eine tiefe Kopie von ls ?

13voto

Konrad Rudolph Punkte 503837

Hier hält ls den Zeiger auf char. Wenn der Kopierkonstruktor nicht zur Verfügung gestellt wird, wird der Standardkopierkonstruktor die tiefe Kopie durchführen?

Der Standard-Kopierkonstruktor kopiert alle Mitglieder, d.h. er ruft ihre jeweiligen Kopierkonstruktoren auf. 1 Also ja, eine std::vector (die in Bezug auf C++ nichts Besonderes sind) werden ordnungsgemäß kopiert werden.

Allerdings ist der Speicher, auf den die Option char* Elemente innerhalb des Vektors natürlich nicht, da C++ nicht weiß und sich auch nicht darum kümmert, worauf die Zeiger zeigen.

Die Lösung besteht jedoch nicht darin, einen eigenen Kopierkonstruktor bereitzustellen. Es ist die Verwendung einer Datenstruktur anstelle von rohen Zeigern ( char* ) der dies tut. Und das ist zufällig std::string (oder std::vector<char> je nach Absicht).


1 Dadurch wird eine transitive Schließung des Kopiervorgangs - auf diese Weise wird das tiefe Kopieren im Allgemeinen implementiert, aber natürlich kann ein Implementierer des Kopiervorgangs jederzeit davon abweichen.

8voto

Johann Gerell Punkte 24065

wird der Standardkopie-Konstruktor die tiefe Kopie durchführen?

Nein, natürlich nicht. Der Compiler kann nicht wissen, wem der Speicher gehört, auf den gezeigt wird.

Wenn eine tiefe Kopie erforderlich ist, müssen Sie den Kopierkonstruktor implementieren und jede char* in neuen Speicher für die vector in der kopiert-zu object .

Wenn Sie die char* als null-terminierte Zeichenketten, dann sollten Sie realmente verwenden. std::string stattdessen. Wenn Sie dies tun, ist der Standardkonstruktor ausreichend.

2voto

PlasmaHH Punkte 15095

Nein, das wird sie nicht.

C++ ruft den Kopier-Ctor aller Unterobjekte rekursiv auf. Es wird also den Kopier-Ctor des Vektors aufrufen, der wiederum den Kopier-Ctor des char* die die char* nach Wert. C++ wird niemals automatisch Speicher zuweisen und die Daten kopieren. Das kann es auch gar nicht, da es nicht weiß, auf welche Daten Sie zeigen und wie viel es kopieren soll.

Wenn Sie Zeichenketten verwenden, sollten Sie lieber die std::string da dies alle Kopiervorgänge für Sie übernimmt. Wenn es sich um einen binären Datenpuffer handelt, der eine besondere Behandlung benötigt, dann müssen Sie das selbst in Ihrem Kopier-Ctor tun (und wenn Sie fertig sind, denken Sie einen Moment darüber nach, ob es wirklich sinnvoll war, von C++ zu verlangen, das für Sie zu tun).

Wenn Sie Ihren eigenen Kopier-Ctor schreiben, sollten Sie immer die Die Dreier-Regel

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X