2013-07-24 12 views
8

Von cplusplus.com kopieren:C++ Konstruktor mit shared_ptr Mitgliedern

Selten werden Sie über eine Klasse kommen, die nicht roh Zeiger enthalten noch der Standard-Copy-Konstruktor ist nicht ausreichend. Ein Beispiel für diese ist, wenn Sie ein Referenzobjekt haben. boost :: shared_ptr <> ist Beispiel.

Kann jemand näher darauf eingehen? Wenn wir eine Klasse haben, die eine boost::shared_ptr enthält, wird diese Kopie nicht erstellt, wenn die Klasse eine Kopie erstellt - und wird daher der shared_ptr Konstruktor nicht das Richtige tun und die Referenzzahl erhöhen? Der folgende Code zum Beispiel Kopien Inner richtig - warum nicht diese Arbeit für shared_ptr:

#include <iostream> 
using namespace std; 

class Inner 
{ 
public: 
Inner() { cout << "inner default constructed" << endl;} 
Inner(const Inner& other) { cout << "inner properly copied" << endl;} 
}; 

class Outer 
{ 
Inner i; 
}; 

int main() { Outer o; Outer p(o); return 0;} 
+8

Vielleicht sind Sie nicht durch die fehlenden doppelten Negative, die nicht in dieser Aussage enthalten sind, nicht gestolpert? –

+0

Vergiss es, es ist nur bollocks. Tun Sie so, als ob shared_ptr nicht erwähnt würde. Ich denke, das ist noch einer der Gründe, warum cplusplus.com so geschmäht wird. –

+0

So eine bessere Frage dann zu stellen. Wenn Leute sagen "der Standardkopiekonstruktor macht eine flache Kopie" bedeutet das, dass "er die Kopierkonstruktoren aller Mitglieder der Reihe nach aufruft" oder "er tut einfach memcpy() auf der Klasseninstanz" –

Antwort

12

Der standardmäßige Kopierkonstruktor verwendet den Kopierkonstruktor für jede Elementvariable oder bitweise Kopie für integrierte Typen.

Wenn Sie einen freigegebenen Zeiger einer Art verwenden, inkrementiert der Kopierkonstruktor die gemeinsame Zählung und sowohl das ursprüngliche als auch das neue Objekt zeigen auf das gleiche Objekt.

In einigen Fällen ist dies das, was Sie wollen; Kopieren des Zeigers und korrektes Verwalten der Referenzzählung, sodass die Ressource freigegeben werden kann, wenn sie nicht mehr verwendet wird.

Der Kontext des zitierten Artikels besteht darin, ein ganzes Objekt zu kopieren. In diesem Fall würde jedes Objekt eine eigene Kopie seiner Unterobjekte haben und Unterobjekte nicht mit anderen Instanzen teilen. In diesem Fall ist shared_ptr wahrscheinlich die falsche Wahl und wird die Unterobjekte definitiv nicht tief kopieren.

Der Absatz ist schlecht formuliert, aber ich bin mir sicher, dass es über Deep-Copy spricht, aber sagen, dass shared_ptr wird nicht diese Deep-Kopie bieten. Das stimmt, denn dafür ist es nicht gedacht.

1

Ich denke, es bedeutet, dass die neue Klasse der alten Klasse der Ressource beziehen, in dem Sie eine Kopie erwarten könnte? von der alten Ressource für die neue Klasse gemacht werden, wie es passieren würde, wenn es ein vollwertiges Mitglied der Klasse wäre. Entweder ist akzeptabel - es hängt davon ab, was Sie tun.

Wenn Sie beispielsweise einen Hund kopieren und ein Hund einen Knochen hat, erhält der neue Hund seinen eigenen Knochen oder teilt er den ursprünglichen Knochen?

+0

Das ist, was der vorherige Absatz in dem verknüpften Artikel beschreibt; Wenn das Objekt einen rohen Zeiger auf eine Ressource enthält, die es verwaltet (was normalerweise eine sehr schlechte Idee ist), dann brauchen Sie einen Kopierkonstruktor, um damit umzugehen. Der zitierte Absatz ist einfach Kauderwelsch. –

+0

Wenn das kopierte Objekt eine Kopie der ursprünglichen Ressource haben und nicht teilen soll, benötigen Sie einen Kopierkonstruktor, wenn Sie shared_ptr –

+0

Ich sehe. Ja, vielleicht versucht der Autor zu sagen, dass Sie einen Kopierkonstruktor benötigen, wenn Sie einen Shared-Pointer verwenden, wenn Sie seine Shared-Semantik nicht wollen. Das ist allerdings etwas merkwürdig. –

5

Kann jemand näher darauf eingehen?

Nicht wirklich; es ist Kauderwelsch.

Wenn wir eine Klasse haben ein boost::shared_ptr enthält, wird das nicht gebaut bekommen Kopie, wenn die Klasse gebaut wird Kopie - und damit auch nicht der shared_ptr Konstruktor das Richtige zu tun und die Referenzzähler erhöhen?

Das stimmt. shared_ptr ist richtig mit einer gültigen Kopiesemantik entworfen, so dass es nicht nötig ist, speziell damit umzugehen, wenn ein Klassenobjekt mit einem kopiert wird.

Möglicherweise meinte der Autor, dass Sie einen Kopierkonstruktor benötigen, um einen neuen zu erstellen, wenn Sie das gemeinsame Objekt kopieren und nicht teilen möchten. Es ist jedoch merkwürdig, eine shared_ptr zu verwenden, wenn Sie keine gemeinsame Eigentümerschaft wünschen.

Verwandte Themen