web-dev-qa-db-de.com

Was ist der Unterschied zwischen einer tiefen Kopie und einer flachen Kopie?

Was ist der Unterschied zwischen einer tiefen Kopie und einer flachen Kopie?

754
David Locke

Flache Kopien werden so wenig wie möglich kopiert. Eine flache Kopie einer Sammlung ist eine Kopie der Sammlungsstruktur, nicht die Elemente. Bei einer flachen Kopie teilen nun zwei Sammlungen die einzelnen Elemente.

Tiefe Kopien kopieren alles. Eine tiefe Kopie einer Sammlung besteht aus zwei Sammlungen, bei denen alle Elemente der Originalsammlung dupliziert sind. 

645
S.Lott

Breite gegen Tiefe; Denken Sie in Bezug auf einen Referenzbaum mit Ihrem Objekt als Wurzelknoten.

Flach:

Before CopyShallow CopyingShallow Done

Die Variablen A und B beziehen sich auf unterschiedliche Speicherbereiche. Wenn B zu A zugewiesen wird, beziehen sich die beiden Variablen auf denselben Speicherbereich. Spätere Änderungen am Inhalt von beiden werden sofort in den Inhalt anderer übernommen, da sie den Inhalt teilen.

Tief:

Before CopyDeep CopyingDeep Done

Die Variablen A und B beziehen sich auf unterschiedliche Speicherbereiche, wenn B A zugewiesen wird, werden die Werte in dem 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.

753
dlamblin

Kurz gesagt, es hängt davon ab, was auf was zeigt. In einer flachen Kopie zeigt Objekt B auf die Position des Objekts A im Speicher. In der tiefen Kopie werden alle Objekte im Speicherbereich von Objekt A in den Speicherplatz von Objekt B kopiert.

Dieser Wiki-Artikel enthält ein tolles Diagramm.

http://en.wikipedia.org/wiki/Object_copy

141
helloandre

Speziell für iOS-Entwickler:  

Wenn B eine flache Kopie von A ist, dann ist dies für primitive Daten wie B = [A assign]; und für Objekte wie B = [A retain];

B und A zeigen auf den gleichen Speicherplatz

Wenn B eine tiefe Kopie von A ist, dann ist es wie B = [A copy];

B und A verweisen auf verschiedene Speicherplätze

B Speicheradresse ist identisch mit der von A

B hat den gleichen Inhalt wie A's

68
Abhishek Bedi

Versuchen Sie folgendes Bild zu betrachten

 enter image description here

Zum Beispiel erstellt Object.MemberwiseClone eine shallow copy link

und mithilfe der ICloneable - Schnittstelle können Sie deep kopieren, wie beschrieben hier

63
Alexandr

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:

class String
{
     int   size;
     char* data;
};

String  s1("Ace");   // s1.size = 3 s1.data=0x0000F000

String  s2 = shallowCopy(s1);
 // s2.size =3 s2.data = 0X0000F000
String  s3 = deepCopy(s1);
 // s3.size =3 s3.data = 0x0000F00F
 //                      (With Ace copied to this location.)
60
Martin York

Ich habe hier keine kurze, leicht verständliche Antwort gesehen - also versuche ich es.

Bei einer flachen Kopie wird jedes Objekt, auf das die Quelle zeigt, auch vom Ziel gezeigt (damit keine referenzierten Objekte kopiert werden).

Bei einer tiefen Kopie wird jedes Objekt, auf das die Quelle zeigt, kopiert und das Ziel wird auf die Kopie gezeigt (also gibt es jetzt 2 von jedem referenzierten Objekt). Dies rekursiv den Objektbaum.

44
Bill K

Der Einfachheit halber können Sie diesem Artikel folgen: https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm


Flache Kopie:

 Shallow Copy


Tiefe Kopie:

 Deep Copy

36
Touchstone

{Stellen Sie sich zwei Objekte vor: A und B des gleichen Typs _t (in Bezug auf C++) und Sie denken darüber nach, A nach B zu kopieren.}

Flache Kopie: Erstellt einfach eine Kopie des Verweises auf A in B. Stellen Sie sich dies als Kopie der Adresse von A vor. Die Adressen von A und B sind also gleich, d. H. Sie zeigen auf den gleichen Speicherplatz, d. H. Auf Dateninhalte.

Deep Copy: Erstellt einfach eine Kopie aller Mitglieder von A, ordnet Speicher an einem anderen Ort für B zu und weist dann die kopierten Mitglieder B zu, um dies zu erreichen tiefe Kopie. Auf diese Weise ist, wenn A nicht mehr existiert, B im Speicher noch gültig. Der richtige Begriff wäre Klonen, wenn Sie wissen, dass beide völlig gleich, aber doch unterschiedlich sind (d. H. 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 während des Deep Copy ausgewählt werden sollen. Dies ist eine übliche Vorgehensweise beim Erstellen von APIs.

Sie können eine flache Kopie erstellen , NUR wenn Sie die Einsätze verstehen. Wenn Sie eine enorme Anzahl von Zeigern in C++ oder C haben, ist das Erstellen einer flachen Kopie eines Objekts WIRKLICH eine schlechte Idee.

Example_OF_DEEP COPY _ Wenn Sie beispielsweise versuchen, eine Bildverarbeitung und Objekterkennung durchzuführen, müssen Sie "Irrelevante und sich wiederholende Bewegungen" aus Ihren Verarbeitungsbereichen ausblenden . Wenn Sie Bildzeiger verwenden, verfügen Sie möglicherweise über die Spezifikation zum Speichern dieser Maskenbilder. JETZT ... Wenn Sie eine flache Kopie des Bildes erstellen und die Zeigerreferenzen vom Stapel GETRENNT werden, haben Sie die Referenz und ihre Kopie verloren, d. H., Irgendwann tritt ein Laufzeitfehler aufgrund einer 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.

Example_OF_SHALLOW_COPY Ich bin im Vergleich zu den Benutzern in StackOverflow nicht sehr sachkundig. Sie können diesen Teil also löschen und ein gutes Beispiel einfügen, wenn Sie dies klären können. Aber ich denke wirklich, es ist keine gute Idee, eine flache Kopie zu erstellen, wenn Sie wissen, dass Ihr Programm für einen unendlichen Zeitraum ausgeführt wird, d. H. Eine kontinuierliche "Push-Pop" -Operation über den Stapel mit Funktionsaufrufen. Wenn Sie einem Amateur oder Anfänger etwas vorführen (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 regelmäßig kopieren, da dies Ihr Programm früher oder später zum Erliegen bringt.

35
ha9u63ar
char * Source = "Hello, world.";

char * ShallowCopy = Source;    

char * DeepCopy = new char(strlen(Source)+1);
strcpy(DeepCopy,Source);        

'ShallowCopy' zeigt auf dieselbe Position im Speicher wie 'Source'. _. 'DeepCopy' zeigt auf eine andere Position im Speicher, der Inhalt ist jedoch derselbe.

30
John Dibling

Was ist Flachkopie?

Die flache Kopie ist eine bitweise Kopie eines Objekts. Ein neues Objekt wird erstellt, das eine exakte Kopie der Werte im ursprünglichen Objekt enthält. Wenn eines der Felder des Objekts Verweise auf andere Objekte sind, werden nur die Referenzadressen kopiert, d. H. Nur die Speicheradresse wird kopiert. Shallow Copy

In dieser Abbildung hat der MainObject1 Felder field1 vom Typ int und ContainObject1 vom Typ ContainObject. Wenn Sie eine flache Kopie von MainObject1 erstellen, wird MainObject2 mit field2 erstellt, der den kopierten Wert von field1 enthält und weiterhin auf ContainObject1 selbst verweist. Da field1 vom primitiven Typ ist, wird sein Wert in field2 kopiert. Da ContainedObject1 jedoch ein Objekt ist, zeigt MainObject2 weiterhin auf ContainObject1. Daher werden alle Änderungen, die an ContainObject1 in MainObject1 vorgenommen wurden, in MainObject2 wiedergegeben.

Wenn es sich hierbei um eine flache Kopie handelt, können Sie sehen, welche Kopie tief ist. 

Was ist Deep Copy?

Eine tiefe Kopie kopiert alle Felder und erstellt Kopien von dynamisch zugewiesenem Speicher, auf den die Felder zeigen. Eine tiefe Kopie tritt auf, wenn ein Objekt zusammen mit den Objekten kopiert wird, auf die es verweist. Deep Copy

In dieser Abbildung enthält das MainObject1 Felder field1 vom Typ int und ContainObject1 vom Typ ContainObject. Wenn Sie eine tiefe Kopie von MainObject1 erstellen, wird MainObject2 erstellt, wobei field2 den kopierten Wert von field1 und ContainObject2 den kopierten Wert von ContainObject1 enthält. Beachten Sie, dass Änderungen an ContainObject1 in MainObject1 nicht in MainObject2 übernommen werden. 

guter Artikel

20
atish shimpi

Bei der objektorientierten Programmierung enthält ein Typ eine Sammlung von Elementfeldern. Diese Felder können entweder als Wert oder als Referenz (d. H. 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 Verweise auf die ursprünglichen Objekte. Alle Änderungen an den Elementen, die als Verweise gespeichert werden, werden sowohl im Original als auch in der Kopie angezeigt, da das referenzierte Objekt nicht kopiert wurde.

In einer tiefen Kopie werden die nach Wert gespeicherten Felder wie zuvor kopiert, die Zeiger auf Objekte, die als Referenz gespeichert sind, werden jedoch nicht kopiert. Stattdessen wird eine tiefe Kopie des referenzierten Objekts erstellt und ein Zeiger auf das neue Objekt gespeichert. Alle Änderungen, die an diesen referenzierten Objekten vorgenommen werden, wirken sich nicht auf andere Kopien des Objekts aus.

15

'ShallowCopy' zeigt auf dieselbe Stelle im Speicher wie 'Source'. 'DeepCopy' zeigt auf einen anderen Speicherort, der Inhalt ist jedoch gleich.

12
GovindaRaju
var source = { firstName="Jane", lastname="Jones" };
var shallow = ShallowCopyOf(source);
var deep = DeepCopyOf(source);
source.lastName = "Smith";
WriteLine(source.lastName); // prints Smith
WriteLine(shallow.lastName); // prints Smith
WriteLine(deep.lastName); // prints Jones
8
Dour High Arch

Shallow Copy - Die Referenzvariable in ursprünglichen und flach kopierten Objekten hat eine Referenz auf common object.

Deep Copy - Die Referenzvariable in originalen und tief kopierten Objekten hat eine Referenz auf anderes Objekt.

klon macht immer flaches Kopieren.

public class Language implements Cloneable{

    String name;
    public Language(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

hauptklasse ist folgende

public static void main(String args[]) throws ClassNotFoundException, CloneNotSupportedException{

      ArrayList<Language> list=new ArrayList<Language>();
      list.add(new Language("C"));
      list.add(new Language("Java"));

      ArrayList<Language> shallow=(ArrayList<Language>) list.clone();
      //We used here clone since this always shallow copied.

      System.out.println(list==shallow);

      for(int i=0;i<list.size();i++)
      System.out.println(list.get(i)==shallow.get(i));//true

      ArrayList<Language> deep=new ArrayList<Language>();
      for(Language language:list){
          deep.add((Language) language.clone());
      }
      System.out.println(list==deep);
      for(int i=0;i<list.size();i++)
          System.out.println(list.get(i)==deep.get(i));//false

} 

OutPut von oben wird

falsch wahr wahr 

falsch falsch falsch

Jede Änderung, die an einem originalen Objekt vorgenommen wird, spiegelt sich in einem flachen Objekt wider, nicht in einem tiefen Objekt.

  list.get(0).name="ViSuaLBaSiC";
  System.out.println(shallow.get(0).getName()+"  "+deep.get(0).getName());

OutPut- ViSuaLBaSiC C 

7
user4768611

Flaches Klonen:
Definition: "Eine flache Kopie eines Objekts kopiert das 'main'-Objekt, kopiert jedoch nicht die inneren Objekte." Wenn ein benutzerdefiniertes Objekt (z. B. Employee) nur primitive Variablen vom Typ String enthält, verwenden Sie Shallow Cloning. 

Employee e = new Employee(2, "john cena");
Employee e2=e.clone();

Sie geben super.clone(); in der überschriebenen Klonmethode () zurück, und Ihr Job ist beendet.

Deep Cloning :
Definition: "Im Gegensatz zur flachen Kopie ist eine tiefe Kopie eine vollständig unabhängige Kopie eines Objekts."
Bedeutet, wenn ein Employee-Objekt ein anderes benutzerdefiniertes Objekt enthält: 

Employee e = new Employee(2, "john cena", new Address(12, "West Newbury", "Massachusetts");

Dann müssen Sie den Code schreiben, um das 'Address'-Objekt in der überschriebenen clone () -Methode zu klonen. Andernfalls wird das Address-Objekt nicht geklont und es verursacht einen Fehler, wenn Sie den Wert von Address in geklontem Employee-Objekt ändern.

7
Arun Raaj

Tiefe Kopie

Eine tiefe Kopie kopiert alle Felder und erstellt Kopien von dynamisch zugewiesenem Speicher, auf den die Felder zeigen. Eine tiefe Kopie tritt auf, wenn ein Objekt zusammen mit den Objekten kopiert wird, auf die es verweist. 

Flache Kopie

Die flache Kopie ist eine bitweise Kopie eines Objekts. Ein neues Objekt wird erstellt, das eine exakte Kopie der Werte im ursprünglichen Objekt enthält. Wenn eines der Felder des Objekts Verweise auf andere Objekte sind, werden nur die Referenzadressen kopiert, d. H. Nur die Speicheradresse wird kopiert.

Beispiel für tiefe Kopie und flache Kopie

6

Ich möchte eher ein Beispiel als eine formale Definition geben.

var originalObject = { 
    a : 1, 
    b : 2, 
    c : 3,
};

Dieser Code zeigt eine flache Kopie :

var copyObject1 = originalObject;

console.log(copyObject1.a);         // it will print 1 
console.log(originalObject.a);       // it will also print 1 
copyObject1.a = 4; 
console.log(copyObject1.a);           //now it will print 4 
console.log(originalObject.a);       // now it will also print 4

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // now it will print 1

Dieser Code zeigt eine tiefe Kopie :

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // !! now it will print 1 !!
6
Vivek Mehta

In einfachen Begriffen ähnelt eine flache Kopie Call By Reference und eine Deep Copy ähnelt Call By Value

In Call By Reference beziehen sich sowohl die formalen als auch die aktuellen Parameter einer Funktion auf denselben Speicherplatz und den Wert.

In Call By Value beziehen sich sowohl formale als auch tatsächliche Parameter einer Funktion auf einen anderen Speicherplatz, der jedoch denselben Wert hat.

5
santhosh

Stellen Sie sich vor, es gibt zwei Arrays mit den Namen arr1 und arr2. 

arr1 = arr2;   //shallow copy
arr1 = arr2.clone(); //deep copy
5
PeerNet
struct sample
{
    char * ptr;
}
void shallowcpy(sample & dest, sample & src)
{
    dest.ptr=src.ptr;
}
void deepcpy(sample & dest, sample & src)
{
    dest.ptr=malloc(strlen(src.ptr)+1);
    memcpy(dest.ptr,src.ptr);
}
5
notytony

Eine flache Kopie erstellt ein neues zusammengesetztes Objekt und fügt seine Referenzen in 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.

import copy
x =[1,[2]]
y=copy.copy(x)
z= copy.deepcopy(x)
print(y is z)

Der obige Code druckt FALSCH.

Mal sehen wie.

Ursprüngliches zusammengesetztes Objekt x=[1,[2]] (wird als zusammengesetztes Objekt bezeichnet, da es ein Objekt innerhalb des Objekts enthält (Inception)).

 enter image description here

wie Sie im Bild sehen können, gibt es eine Liste in der Liste.

Dann erstellen wir mit y = copy.copy(x) eine flache Kopie davon. Was Python hier tut, ist, dass es ein neues zusammengesetztes Objekt erstellt, die darin enthaltenen Objekte jedoch auf die ursprünglichen Objekte zeigen.

 enter image description here

In dem 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 Tiefenkopie davon mit z = copy.deepcopy(x). Was Python hier tut, erzeugt ein neues Objekt für die äußere Liste sowie für die innere Liste. wie in der Abbildung unten gezeigt (rot hervorgehoben).

 enter image description here

Am Ende des Codes werden False gedruckt, da y und z nicht die gleichen Objekte sind.

HTH.

2
Sushant

Um weitere Antworten hinzuzufügen, 

  • eine flache Kopie eines Objekts führt für Werttyp -basierte Eigenschaften eine Kopie nach Wert aus, und Referenzobjekte für Referenztypen.
  • eine tiefe Kopie eines Objekts führt für Werttypen eine Kopie nach Wert durchproperties sowie für Referenztypen um eine Kopie nach Wertproperties tief in der Hierarchie (von Referenztypen).
2
VS1

Entnommen aus [blog]: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

Deep copy beinhaltet die Verwendung des Inhalts eines Objekts, um eine weitere Instanz derselben Klasse zu erstellen. In einer tiefen Kopie enthalten die beiden Objekte möglicherweise dieselben Informationen, das Zielobjekt verfügt jedoch über eigene Puffer und Ressourcen. Die Zerstörung eines der Objekte wirkt sich nicht auf das verbleibende Objekt aus. Der überladene Zuweisungsoperator erstellt eine tiefe Kopie von Objekten.

Shallow copy beinhaltet das Kopieren des Inhalts eines Objekts in eine andere Instanz derselben Klasse, wodurch ein Spiegelbild erstellt wird. Aufgrund des direkten Kopierens von Referenzen und Zeigern teilen sich die beiden Objekte die gleichen extern enthaltenen Inhalte des anderen Objekts, um unvorhersehbar zu sein.

Erklärung:

Mit einem Kopierkonstruktor kopieren wir einfach die Datenwerte member nach member. Diese Kopiermethode wird als flache Kopie bezeichnet. Wenn das Objekt eine einfache Klasse ist, bestehend aus eingebauten Typen und keinen Zeigern, ist dies akzeptabel. Diese Funktion würde die Werte und die Objekte verwenden und ihr Verhalten würde nicht mit einer flachen Kopie geändert. Es werden nur die Adressen von Zeigern kopiert, die Mitglieder sind, und nicht der Wert, auf den die Adresse verweist. Die Datenwerte des Objekts würden dann unbeabsichtigt durch die Funktion geändert. Wenn die Funktion den Gültigkeitsbereich verlässt, wird die Kopie des Objekts mit allen Daten vom Stapel entfernt.

Wenn das Objekt über Zeiger verfügt, muss eine tiefe Kopie ausgeführt werden. Mit der tiefen Kopie eines Objekts wird Speicher für das im freien Speicher befindliche Objekt zugewiesen, und die Elemente, auf die gezeigt wird, werden kopiert. Eine tiefe Kopie wird für Objekte verwendet, die von einer Funktion zurückgegeben werden.

2
Santosh

Bei einer flachen Kopie wird keine neue Referenz erstellt, bei einer tiefen Kopie wird die neue Referenz erstellt.

Hier ist das Programm, um die tiefe und flache Kopie zu erklären.

public class DeepAndShollowCopy {
    int id;
    String name;
    List<String> testlist = new ArrayList<>();

    /*
    // To performing Shallow Copy 
    // Note: Here we are not creating any references. 
      public DeepAndShollowCopy(int id, String name, List<String>testlist)
       { 

       System.out.println("Shallow Copy for Object initialization");
       this.id = id; 
       this.name = name; 
       this.testlist = testlist; 

       }
    */  

    // To performing Deep Copy 
    // Note: Here we are creating one references( Al arraylist object ). 
    public DeepAndShollowCopy(int id, String name, List<String> testlist) {
        System.out.println("Deep Copy for Object initialization");
        this.id = id;
        this.name = name;
        String item;
        List<String> Al = new ArrayList<>();
        Iterator<String> itr = testlist.iterator();
        while (itr.hasNext()) {
            item = itr.next();
            Al.add(item);
        }
        this.testlist = Al;
    }


    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Oracle");
        list.add("C++");
        DeepAndShollowCopy copy=new DeepAndShollowCopy(10,"Testing", list);
        System.out.println(copy.toString());
    }
    @Override
    public String toString() {
        return "DeepAndShollowCopy [id=" + id + ", name=" + name + ", testlist=" + testlist + "]";
    }
}
2
Lova Chittumuri

Shallow - Kopieren 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. für einen Referenztyp -> wird die Referenz kopiert, das referenzierte Objekt jedoch nicht; Daher beziehen sich das Originalobjekt 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 value-Typ ist, wird -> eine bitweise Kopie des Felds 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.

2
Rajaram Shelar

Ararys kopieren:

Array ist eine Klasse. Dies bedeutet, dass es sich um einen Referenztyp handelt, sodass array1 = array2 resultiert.

Aber schau dir dieses Beispiel an:

  static void Main()
    {
        int[] arr1 = new int[] { 1, 2, 3, 4, 5 }; 
        int[] arr2 = new int[] { 6, 7, 8, 9, 0 };

        Console.WriteLine(arr1[2] + " " + arr2[2]);
        arr2 = arr1;
        Console.WriteLine(arr1[2] + " " + arr2[2]); 
        arr2 = (int[])arr1.Clone();
        arr1[2] = 12;
        Console.WriteLine(arr1[2] + " " + arr2[2]);
    }

shallow clone bedeutet, dass nur der durch das geklonte Array dargestellte Speicher kopiert wird. 

Wenn das Array Werttypobjekte enthält, werden die Werte kopiert

Wenn das Array einen Referenztyp enthält, werden nur die Referenzen kopiert. Daher gibt es zwei Arrays, deren Member 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. 

1
lukaszk

Mit dem Kopierkonstruktor wird das neue Objekt mit dem zuvor erstellten Objekt derselben Klasse initialisiert. Standardmäßig hat der Compiler eine flache Kopie geschrieben. Flache Kopien funktionieren gut, wenn keine dynamische Speicherzuweisung erforderlich ist, da bei dynamischer Speicherzuweisung beide Objekte auf den gleichen Speicherort in einem Heap zeigen. Um dieses Problem zu beheben, haben wir eine tiefe Kopie geschrieben, sodass beide Objekte ihre eigene Attributkopie haben in a memory . Um die Details mit vollständigen Beispielen und Erklärungen zu lesen, können Sie den Artikel C++ - Konstruktoren sehen.

0
royal52

Um nur ein wenig mehr für Verwirrung zwischen flachen Kopien hinzuzufügen und der Liste einfach einen neuen Variablennamen zuzuweisen.

"Sagen wir, wir haben:

x = [
    [1,2,3],
    [4,5,6],
    ]

Diese Anweisung erstellt 3 Listen: 2 innere Listen und eine äußere Liste. Ein Verweis auf die äußere Liste wird dann unter dem Namen x zur Verfügung gestellt. Wenn wir es tun

y = x

es werden keine Daten kopiert. Wir haben immer noch die gleichen 3 Listen im Speicher. Dazu wird die äußere Liste zusätzlich zu ihrem vorherigen Namen x unter dem Namen y verfügbar gemacht. Wenn wir es tun

y = list(x)

oder

y = x[:]

Dadurch wird eine neue Liste mit demselben Inhalt wie x erstellt. Liste x enthielt einen Verweis auf die beiden inneren Listen, sodass die neue Liste auch einen Verweis auf diese beiden inneren Listen enthält. Es wird nur eine Liste kopiert - die äußere Liste ... __ Jetzt befinden sich 4 Listen im Speicher, die beiden inneren Listen, die äußere Liste und die Kopie der äußeren Liste. Die ursprüngliche äußere Liste ist unter dem Namen x verfügbar, und die neue äußere Liste ist unter dem Namen y verfügbar.

Die inneren Listen wurden nicht kopiert! Sie können die inneren Listen an dieser Stelle entweder von x oder y aus aufrufen und bearbeiten!

Wenn Sie über eine zweidimensionale (oder höhere) Liste oder eine verschachtelte Datenstruktur verfügen und eine vollständige Kopie aller Elemente erstellen möchten, möchten Sie die Funktion deepcopy () im Kopiermodul verwenden. Ihre Lösung funktioniert auch für 2-D-Listen, indem Sie die Elemente in der äußeren Liste durchlaufen, eine Kopie von jeder von ihnen erstellen und dann eine neue äußere Liste für alle inneren Kopien erstellen. "

source: https://www.reddit.com/r/learnpython/comments/1afldr/why_is_copying_a_list_so_damn_difficult_in_python/

0
Lance Ruo Zhang

Ich kam aus den folgenden Zeilen zu verstehen.

Eine flache Kopie kopiert ein Objekt value type (int, float, bool) in Felder des Zielobjekts und die Referenztypen des Objekts (Zeichenfolge, Klasse usw.) werden als referenzen im Zielobjekt kopiert. In diesem Ziel zeigen 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.

0

Zusätzlich zu den obigen Definitionen befindet sich eine weitere und am häufigsten verwendete tiefe Kopie im Kopierkonstruktor (oder im Ü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 der Zeitpunkt, zu dem Sie sich für die Implementierung einer Kopierkonstruktor- oder Überladungszuweisung in Ihrer Klasse entschieden haben und das Kopieren aller Klassenmitglieder zulässt.

MyClass& MyClass(const MyClass& obj) // copy constructor for MyClass
{
          // write your code, to copy all the members and return the new object
}
MyClass& operator=(const MyClass& obj) // overloading assignment operator,
{
          // write your code, to copy all the members and return the new object
}
0