Was ist der Unterschied zwischen einer tiefen und einer flachen Kopie?
language-agnostic
copy
deep-copy
shallow-copy
David Locke
quelle
quelle
Antworten:
Flache Kopien werden so wenig wie möglich dupliziert. Eine flache Kopie einer Sammlung ist eine Kopie der Sammlungsstruktur, nicht der Elemente. Mit einer flachen Kopie teilen sich nun zwei Sammlungen die einzelnen Elemente.
Tiefe Kopien duplizieren alles. Eine tiefe Kopie einer Sammlung besteht aus zwei Sammlungen, bei denen alle Elemente der ursprünglichen Sammlung dupliziert wurden.
quelle
Breite gegen Tiefe; Denken Sie an einen Referenzbaum mit Ihrem Objekt als Wurzelknoten.
Flach:
Die Variablen A und B beziehen sich auf verschiedene Speicherbereiche. Wenn B A zugewiesen ist, beziehen sich die beiden Variablen auf denselben Speicherbereich. Spätere Änderungen am Inhalt von beiden werden sofort in den Inhalten anderer wiedergegeben, da sie Inhalte gemeinsam nutzen.
Tief:
Die Variablen A und B beziehen sich auf verschiedene Speicherbereiche, wenn B A zugewiesen wird, werden die Werte im Speicherbereich, auf die A zeigt, in den Speicherbereich kopiert, auf den B zeigt. Spätere Änderungen am Inhalt von entweder bleiben für A oder B eindeutig. Der Inhalt wird nicht geteilt.
quelle
Kurz gesagt, es kommt darauf an, was auf was hinweist. In einer flachen Kopie zeigt Objekt B auf die Position von Objekt A im Speicher. Beim tiefen Kopieren werden alle Dinge im Speicherort von Objekt A in den Speicherort von Objekt B kopiert.
Dieser Wiki-Artikel hat ein tolles Diagramm.
http://en.wikipedia.org/wiki/Object_copy
quelle
Versuchen Sie, das folgende Bild zu berücksichtigen
Zum Beispiel erstellt Object.MemberwiseClone eine flache Kopie Link
und über die ICloneable- Schnittstelle können Sie wie hier beschrieben eine tiefe Kopie erhalten
quelle
Speziell für iOS-Entwickler:
Wenn
B
es sich um eine flache Kopie von handeltA
, ist es für primitive Daten wieB = [A assign];
und für Objekte wieB = [A retain]
;B und A zeigen auf denselben Speicherort
Wenn
B
eine ist tiefere Kopie vonA
, dann ist es wieB = [A copy];
B und A zeigen auf unterschiedliche Speicherplätze
Die Speicheradresse B entspricht der von A.
B hat den gleichen Inhalt wie A.
quelle
Flache Kopie: Kopiert die Elementwerte von einem Objekt in ein anderes.
Deep Copy: Kopiert die Elementwerte von einem Objekt in ein anderes.
Alle Zeigerobjekte werden dupliziert und tief kopiert.
Beispiel:
quelle
Ich habe hier keine kurze, leicht verständliche Antwort gesehen - also werde ich es versuchen.
Bei einer flachen Kopie wird jedes Objekt, auf das die Quelle zeigt, auch vom Ziel angezeigt (sodass keine referenzierten Objekte kopiert werden).
Bei einer tiefen Kopie wird jedes Objekt, auf das die Quelle zeigt, kopiert und die Kopie vom Ziel (auf die es jetzt 2 von jedem referenzierten Objekt gibt). Dies wiederholt sich im Objektbaum.
quelle
Zum besseren Verständnis können Sie diesem Artikel folgen: https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm
Flache Kopie:
Deep Copy:
quelle
{Stellen Sie sich zwei Objekte vor: A und B vom gleichen Typ _t (in Bezug auf C ++) und Sie denken darüber nach, A nach B flach / tief zu kopieren}
Flache Kopie: Erstellt einfach eine Kopie des Verweises auf A in B. Stellen Sie sich das als Kopie der Adresse von A vor. Die Adressen von A und B sind also gleich, dh sie zeigen auf den gleichen Speicherort, dh auf den Dateninhalt.
Tiefe Kopie: Erstellt einfach eine Kopie aller Mitglieder von A, weist B Speicher an einem anderen Ort zu und weist die kopierten Mitglieder dann B zu, um eine Deep Copy zu erzielen. Auf diese Weise ist B im Speicher noch gültig, wenn A nicht mehr existiert. Der richtige Begriff wäre Klonen, wenn Sie wissen, dass beide völlig gleich, aber dennoch unterschiedlich sind (dh als zwei verschiedene Entitäten im Speicherbereich gespeichert sind). Sie können auch Ihren Klon-Wrapper bereitstellen, in dem Sie über die Einschluss- / Ausschlussliste entscheiden können, welche Eigenschaften beim Deep Copy ausgewählt werden sollen. Dies ist eine gängige Praxis beim Erstellen von APIs.
Sie können NUR eine flache Kopie erstellen , wenn Sie die damit verbundenen Einsätze verstehen. Wenn Sie in C ++ oder C eine enorme Anzahl von Zeigern haben, ist es WIRKLICH eine schlechte Idee , eine flache Kopie eines Objekts zu erstellen .
BEISPIEL_OF_DEEP COPY_ Ein Beispiel ist, wenn Sie versuchen, Bildverarbeitung und Objekterkennung durchzuführen , müssen Sie "irrelevante und sich wiederholende Bewegung" aus Ihren Verarbeitungsbereichen maskieren. Wenn Sie Bildzeiger verwenden, haben Sie möglicherweise die Spezifikation, um diese Maskenbilder zu speichern. JETZT ... Wenn Sie eine flache Kopie des Bildes erstellen und die Zeigerreferenzen vom Stapel getötet werden, haben Sie die Referenz und ihre Kopie verloren, dh es tritt irgendwann ein Laufzeitfehler bei der Zugriffsverletzung auf. In diesem Fall benötigen Sie eine tiefe Kopie Ihres Bildes, indem Sie es KLONEN. Auf diese Weise können Sie die Masken abrufen, falls Sie sie in Zukunft benötigen.
BEISPIEL_OF_SHALLOW_COPY Ich bin im Vergleich zu den Benutzern in StackOverflow nicht besonders kompetent. Sie können diesen Teil also gerne löschen und ein gutes Beispiel geben, wenn Sie dies klären können. Aber ich denke wirklich, dass es keine gute Idee ist, eine flache Kopie zu erstellen, wenn Sie wissen, dass Ihr Programm für einen unendlichen Zeitraum ausgeführt wird, dh eine kontinuierliche "Push-Pop" -Operation über den Stapel mit Funktionsaufrufen. Wenn Sie einem Amateur oder Anfänger etwas demonstrieren (z. B. C / C ++ - Lernprogramme), ist dies wahrscheinlich in Ordnung. Wenn Sie jedoch eine Anwendung wie ein Überwachungs- und Erkennungssystem oder ein Sonar-Tracking-System ausführen, sollten Sie Ihre Objekte nicht flach kopieren, da dies Ihr Programm früher oder später zum Erliegen bringt.
quelle
'ShallowCopy' zeigt auf dieselbe Stelle im Speicher wie 'Source'. 'DeepCopy' zeigt auf eine andere Stelle im Speicher, aber der Inhalt ist der gleiche.
quelle
Was ist eine flache Kopie?
Flache Kopie ist eine bitweise Kopie eines Objekts. Es wird ein neues Objekt erstellt, das eine exakte Kopie der Werte im Originalobjekt enthält. Wenn eines der Felder des Objekts Verweise auf andere Objekte sind, werden nur die Referenzadressen kopiert, dh nur die Speicheradresse wird kopiert.
In dieser Abbildung hat das
MainObject1
Felderfield1
vom Typ int undContainObject1
vom TypContainObject
. Wenn Sie eine flache Kopie von erstellenMainObject1
,MainObject2
wird diese mitfield2
dem kopierten Wert von erstelltfield1
und zeigt immer noch auf sichContainObject1
selbst. Beachten Sie, dass, dafield1
es sich um einen primitiven Typ handelt, sein Wert kopiert wird,field2
aber daContainedObject1
es sich um ein Objekt handelt, auf dasMainObject2
immer noch verweistContainObject1
. Änderungen anContainObject1
inMainObject1
werden also berücksichtigtMainObject2
.Wenn es sich um eine flache Kopie handelt, sehen wir uns an, was eine tiefe Kopie ist.
Was ist Deep Copy?
Eine tiefe Kopie kopiert alle Felder und erstellt Kopien des dynamisch zugewiesenen Speichers, auf den die Felder zeigen. Eine tiefe Kopie tritt auf, wenn ein Objekt zusammen mit den Objekten, auf die es verweist, kopiert wird.
In dieser Abbildung hat das MainObject1 Felder
field1
vom Typ int undContainObject1
vom TypContainObject
. Wenn Sie eine tiefe Kopie von erstellenMainObject1
,MainObject2
wird mitfield2
dem kopierten Wert vonfield1
undContainObject2
dem kopierten Wert von erstelltContainObject1
. Beachten Sie, dass Änderungen anContainObject1
inMainObject1
nicht in berücksichtigt werdenMainObject2
.guter Artikel
quelle
field3
die, wenn sie in der Lage ist, etwas so Tiefes wie dieses Problem zu verstehen, wo die Nummer 3 in diesem Beispiel stattfindetContainObject2
.Bei der objektorientierten Programmierung enthält ein Typ eine Sammlung von Elementfeldern. Diese Felder können entweder als Wert oder als Referenz (dh als Zeiger auf einen Wert) gespeichert werden.
In einer flachen Kopie wird eine neue Instanz des Typs erstellt und die Werte werden in die neue Instanz kopiert. Die Referenzzeiger werden ebenso wie die Werte kopiert. Daher verweisen die Referenzen auf die Originalobjekte. Alle Änderungen an den Mitgliedern, die als Referenz gespeichert sind, werden sowohl im Original als auch in der Kopie angezeigt, da keine Kopie des referenzierten Objekts erstellt wurde.
In einer tiefen Kopie werden die Felder, die nach Wert gespeichert sind, wie zuvor kopiert, aber die Zeiger auf Objekte, die als Referenz gespeichert sind, werden nicht kopiert. Stattdessen wird eine tiefe Kopie des referenzierten Objekts erstellt und ein Zeiger auf das neue Objekt gespeichert. Änderungen, die an diesen referenzierten Objekten vorgenommen werden, wirken sich nicht auf andere Kopien des Objekts aus.
quelle
'ShallowCopy' zeigt auf dieselbe Stelle im Speicher wie 'Source'. 'DeepCopy' zeigt auf eine andere Stelle im Speicher, aber der Inhalt ist der gleiche.
quelle
Flaches Klonen:
Definition: "Eine flache Kopie eines Objekts kopiert das 'Haupt'-Objekt, kopiert jedoch nicht die inneren Objekte." Wenn ein benutzerdefiniertes Objekt (z. B. Employee) nur primitive Variablen vom Typ String hat, verwenden Sie Shallow Cloning.
Sie kehren
super.clone();
mit der überschriebenen clone () -Methode zurück und Ihr Job ist beendet.Deep Cloning :
Definition: "Im Gegensatz zur flachen Kopie ist eine tiefe Kopie eine völlig unabhängige Kopie eines Objekts."
Bedeutet, wenn ein Mitarbeiterobjekt ein anderes benutzerdefiniertes Objekt enthält:
Dann müssen Sie den Code schreiben, um das 'Address'-Objekt auch in der überschriebenen clone () -Methode zu klonen. Andernfalls wird das Adressobjekt nicht geklont und es tritt ein Fehler auf, wenn Sie den Wert der Adresse im geklonten Mitarbeiterobjekt ändern, der auch den ursprünglichen Wert widerspiegelt.
quelle
quelle
Tiefe Kopie
Eine tiefe Kopie kopiert alle Felder und erstellt Kopien des dynamisch zugewiesenen Speichers, auf den die Felder zeigen. Eine tiefe Kopie tritt auf, wenn ein Objekt zusammen mit den Objekten, auf die es verweist, kopiert wird.
Flache Kopie
Flache Kopie ist eine bitweise Kopie eines Objekts. Es wird ein neues Objekt erstellt, das eine exakte Kopie der Werte im Originalobjekt enthält. Wenn eines der Felder des Objekts Verweise auf andere Objekte sind, werden nur die Referenzadressen kopiert, dh nur die Speicheradresse wird kopiert.
quelle
Flache Kopie - Die Referenzvariable in ursprünglichen und flach kopierten Objekten verweist auf ein gemeinsames Objekt.
Deep Copy - Referenzvariable in ursprünglichen und tief kopierten Objekten verweist auf verschiedene Objekte.
Hauptklasse folgt-
OutPut von oben wird
Jede Änderung am ursprünglichen Objekt spiegelt sich im flachen Objekt wider, nicht im tiefen Objekt.
OutPut- ViSuaLBaSiC C.
quelle
Ich möchte eher ein Beispiel als die formale Definition geben.
Dieser Code zeigt eine flache Kopie :
Dieser Code zeigt eine tiefe Kopie :
quelle
1 1 4 4 4 4 4 4
quelle
In einfachen Worten ähnelt eine flache Kopie Call By Reference und eine Deep Copy Call By Value
In Call By Reference beziehen sich sowohl formale als auch tatsächliche Parameter einer Funktion auf denselben Speicherort und denselben Wert.
In Call By Value beziehen sich sowohl formale als auch tatsächliche Parameter einer Funktion auf unterschiedliche Speicherorte, haben jedoch denselben Wert.
quelle
Stellen Sie sich vor, es gibt zwei Arrays mit den Namen arr1 und arr2.
quelle
Eine flache Kopie erstellt ein neues zusammengesetztes Objekt und fügt seine Verweise auf das ursprüngliche Objekt ein.
Im Gegensatz zur flachen Kopie erstellt deepcopy ein neues zusammengesetztes Objekt und fügt auch Kopien der ursprünglichen Objekte des ursprünglichen zusammengesetzten Objekts ein.
Nehmen wir ein Beispiel.
Der obige Code druckt FALSE.
Mal sehen wie.
Ursprüngliches zusammengesetztes Objekt
x=[1,[2]]
(als zusammengesetzt bezeichnet, da es ein Objekt im Objekt enthält (Inception))Wie Sie auf dem Bild sehen können, befindet sich eine Liste in der Liste.
Dann erstellen wir eine flache Kopie davon mit
y = copy.copy(x)
. Python erstellt hier ein neues zusammengesetztes Objekt, aber die darin enthaltenen Objekte zeigen auf die ursprünglichen Objekte.Im Bild wurde eine neue Kopie für die äußere Liste erstellt. Die innere Liste bleibt jedoch dieselbe wie die ursprüngliche.
Jetzt erstellen wir eine Deepcopy davon mit
z = copy.deepcopy(x)
. Python macht hier ein neues Objekt sowohl für die äußere als auch für die innere Liste. wie im Bild unten gezeigt (rot hervorgehoben).Am Ende wird der Code gedruckt
False
, da y und z nicht dieselben Objekte sind.HTH.
quelle
Beim Flachkopieren wird ein neues Objekt erstellt und anschließend die nicht statischen Felder des aktuellen Objekts in das neue Objekt kopiert. Wenn ein Feld ein Werttyp ist -> wird eine bitweise Kopie des Feldes durchgeführt; für einen Referenztyp -> wird die Referenz kopiert, das referenzierte Objekt jedoch nicht; Daher beziehen sich das ursprüngliche Objekt und sein Klon auf dasselbe Objekt.
Deep Copy erstellt ein neues Objekt und kopiert dann die nicht statischen Felder des aktuellen Objekts in das neue Objekt. Wenn ein Feld ein Werttyp ist -> wird eine bitweise Kopie des Feldes durchgeführt. Wenn ein Feld ein Referenztyp ist -> wird eine neue Kopie des referenzierten Objekts ausgeführt. Die zu klonenden Klassen müssen als [Serializable] gekennzeichnet sein.
quelle
Entnommen aus [Blog]: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
Tiefe Kopie wird der Inhalt eines Objekts verwendet, um eine andere Instanz derselben Klasse zu erstellen. In einer tiefen Kopie können die beiden Objekte dieselben Informationen enthalten, aber das Zielobjekt verfügt über eigene Puffer und Ressourcen. Die Zerstörung eines Objekts hat keine Auswirkungen auf das verbleibende Objekt. Der überladene Zuweisungsoperator würde eine tiefe Kopie von Objekten erstellen.
Beim Flachkopieren wird der Inhalt eines Objekts in eine andere Instanz derselben Klasse kopiert, wodurch ein Spiegelbild erstellt wird. Aufgrund des direkten Kopierens von Referenzen und Zeigern teilen sich die beiden Objekte den gleichen extern enthaltenen Inhalt des anderen Objekts, was unvorhersehbar ist.
Erläuterung:
Mit einem Kopierkonstruktor kopieren wir einfach die Datenwerte Mitglied für Mitglied. Diese Kopiermethode wird als flache Kopie bezeichnet. Wenn das Objekt eine einfache Klasse ist, die aus eingebauten Typen und keinen Zeigern besteht, wäre dies akzeptabel. Diese Funktion würde die Werte und Objekte verwenden und ihr Verhalten würde bei einer flachen Kopie nicht geändert. Es werden nur die Adressen der Zeiger kopiert, die Mitglieder sind, und nicht der Wert, auf den die Adresse zeigt. Die Datenwerte des Objekts würden dann versehentlich von der Funktion geändert. Wenn die Funktion den Gültigkeitsbereich verlässt, wird die Kopie des Objekts mit all seinen Daten vom Stapel genommen.
Wenn das Objekt Zeiger hat, muss eine tiefe Kopie ausgeführt werden. Mit der tiefen Kopie eines Objekts wird Speicher für das Objekt im freien Speicher zugewiesen und die Elemente, auf die verwiesen wird, werden kopiert. Eine tiefe Kopie wird für Objekte verwendet, die von einer Funktion zurückgegeben werden.
quelle
Um anderen Antworten mehr hinzuzufügen,
quelle
Bei einer flachen Kopie wird keine neue Referenz erstellt, bei einer tiefen Kopie wird jedoch die neue Referenz erstellt.
Hier ist das Programm, um die tiefe und flache Kopie zu erklären.
quelle
Kopieren von Ararys:
Array ist eine Klasse, dh es handelt sich um einen Referenztyp. Array1 = Array2 führt zu zwei Variablen, die auf dasselbe Array verweisen.
Aber schauen Sie sich dieses Beispiel an:
Flacher Klon bedeutet, dass nur der durch das geklonte Array dargestellte Speicher kopiert wird.
Wenn das Array Objekte vom Werttyp enthält, werden die Werte kopiert .
Wenn das Array einen Referenztyp enthält, werden nur die Referenzen kopiert. Daher gibt es zwei Arrays, deren Mitglieder auf dieselben Objekte verweisen .
Um eine tiefe Kopie zu erstellen, bei der der Referenztyp dupliziert wird, müssen Sie das Array durchlaufen und jedes Element manuell klonen.
quelle
private void button1_Click(object sender, EventArgs e) { int[] arr1 = new int[]{1,2,3,4,5}; int[] arr2 = new int[]{6,7,8,9,0}; MessageBox.Show(arr1[2] + " " + arr2[2]); arr2 = arr1; MessageBox.Show(arr1[2] + " " + arr2[2]); arr1[2] = 12; MessageBox.Show(arr1[2] + " " + arr2[2]); }
Ich habe aus den folgenden Zeilen verstanden.
Flache Kopie kopiert ein Objekt Werttyp (int, float, bool) Felder zu Zielobjekt und Referenztypen des Objekts (string, Klasse usw.) werden als kopiert Referenzen in Zielobjekt. In diesem Ziel verweisen Referenztypen auf den Speicherort des Quellobjekts.
Deep Copy kopiert den Wert und die Referenztypen eines Objekts in eine vollständig neue Kopie der Zielobjekte. Dies bedeutet, dass sowohl den Werttypen als auch den Referenztypen neue Speicherplätze zugewiesen werden.
quelle
Eine weitere und am häufigsten verwendete Tiefenkopie befindet sich im Kopierkonstruktor (oder Überladungszuweisungsoperator) der Klasse.
Flache Kopie -> ist, wenn Sie keinen Kopierkonstruktor bereitstellen. Hier wird nur das Objekt kopiert, aber nicht alle Mitglieder der Klasse werden kopiert.
Deep Copy -> ist, wenn Sie sich entschieden haben, einen Kopierkonstruktor oder eine Überladungszuweisung in Ihrer Klasse zu implementieren und das Kopieren aller Mitglieder der Klasse zu ermöglichen.
quelle
Der Kopierkonstruktor wird verwendet, um das neue Objekt mit dem zuvor erstellten Objekt derselben Klasse zu initialisieren. Standardmäßig hat der Compiler eine flache Kopie geschrieben. Eine flache Kopie funktioniert einwandfrei, wenn keine dynamische Speicherzuweisung erforderlich ist, da bei einer dynamischen Speicherzuweisung beide Objekte auf denselben Speicherort in einem Heap zeigen. Um dieses Problem zu beheben, haben wir eine tiefe Kopie geschrieben, sodass beide Objekte eine eigene Kopie der Attribute haben in einer Erinnerung. Um die Details mit vollständigen Beispielen und Erklärungen zu lesen, lesen Sie den Artikel C ++ - Konstruktoren .
quelle