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


754

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


6
Unter welche Technologie fällt es?
Suresh Varma

42
@ SureshVarma, es ist ein Programmierkonzept!
Manish Shrivastava

Antworten:


760

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.


Möglicherweise führt die Implementierung von .NET MemberwiseClone () mehr als nur flaches Kopieren im herkömmlichen Sinne
Lu55,

5
Denken Sie daran, dass es auch gemischte Kopien gibt (nicht nur Lazy Copy ), die nur einen Teil davon duplizieren ( hier eine Instanz )! ;)
Cregox

Eine flache Kopie von X kann also die Elemente in X ändern, eine tiefe Kopie jedoch nicht?
Punstress

1
Was ist eine Sammlungsstruktur?
Honig

1
@Honey Collections können verschiedene Datenstrukturen sein, in denen mehrere Datenelemente gespeichert sind. In Python haben wir Tupel, Liste, Wörterbuch usw.
Murphy

850

Breite gegen Tiefe; Denken Sie an einen Referenzbaum mit Ihrem Objekt als Wurzelknoten.

Flach:

Vor dem Kopieren Flaches Kopieren Flach erledigt

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:

Vor dem Kopieren Tiefes Kopieren Tief erledigt

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.


32
Hier ist der Wikipedia - Artikel , dass diese Darstellung von im Fall kommt es macht keinen Sinn, aus dem Zusammenhang für Sie en.wikipedia.org/wiki/Object_copy#Shallow_copy
Corbin

4
Im Falle einer flachen Kopie, wenn wir Änderungen an Array B vornehmen, wird dies in Array A wiedergegeben, da A & B beide auf denselben Speicherort zeigen?
Tek3

3
In einer Zeile seine Kopie als Referenz gegen Kopie nach Wert. Nicht sicher, ob die Antwort richtig ist!
Mannu

2
Bilder direkt aus Wikipedia ohne Zitat
jasonleonhard

9
@jasonleonhard Vor 9 Jahren habe ich den Bildern nur URLs hinzugefügt, da das Einbetten von Bildern nicht unterstützt wurde. Daher hat die URL ihre Quelle angegeben. Die Community hat die URLs später in eingebettete Bilder umgewandelt, ohne dass ein Zitat darauf bearbeitet wurde. Der 4 Jahre alte Top-Kommentar weist auch darauf hin, worauf Sie hinweisen. Schauen Sie sich das an: stackoverflow.com/posts/184780/revisions Warum bearbeiten Sie nicht einfach selbst ein Zitat in der Antwort? Ich bin möglicherweise nicht verfügbar, wenn sich das nächste Mal jemand über meinen 10 Jahre alten Schreibstil beschwert.
Dlamblin

156

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


114

Versuchen Sie, das folgende Bild zu berücksichtigen

Geben Sie hier die Bildbeschreibung ein

Zum Beispiel erstellt Object.MemberwiseClone eine flache Kopie Link

und über die ICloneable- Schnittstelle können Sie wie hier beschrieben eine tiefe Kopie erhalten


28
Ein Bild sagt mehr als tausend Worte.
Levi Fuller

6
Oh Mann, bin hergekommen, um die Bedeutung herauszufinden. Dies ist die einzige Antwort, die geholfen hat.
Karan Singh

1
Dies ist die einfachste und zeigt doch nur, was nötig ist.
hina10531

1
die beste Illustration
Muhammad Nayab

69

Speziell für iOS-Entwickler:

Wenn Bes sich um eine flache Kopie von handelt A, ist es für primitive Daten wie B = [A assign];und für Objekte wieB = [A retain] ;

B und A zeigen auf denselben Speicherort

Wenn Beine ist tiefere Kopie von A, 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.


8
"B-Speicheradresse ist dieselbe wie A" - Wie kommt es?

2
In Deep Copy ist "B-Speicheradresse NICHT die gleiche wie die von A"
ismail baig

60

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.)

47

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.



36

{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.


32
char * Source = "Hello, world.";

char * ShallowCopy = Source;    

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

'ShallowCopy' zeigt auf dieselbe Stelle im Speicher wie 'Source'. 'DeepCopy' zeigt auf eine andere Stelle im Speicher, aber der Inhalt ist der gleiche.


22

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.Flache Kopie

In dieser Abbildung hat das MainObject1Felder field1vom Typ int und ContainObject1vom Typ ContainObject. Wenn Sie eine flache Kopie von erstellen MainObject1, MainObject2wird diese mit field2dem kopierten Wert von erstellt field1und zeigt immer noch auf sich ContainObject1selbst. Beachten Sie, dass, da field1es sich um einen primitiven Typ handelt, sein Wert kopiert wird, field2aber da ContainedObject1es sich um ein Objekt handelt, auf das MainObject2immer noch verweist ContainObject1. Änderungen an ContainObject1in MainObject1werden also berücksichtigt MainObject2.

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. Tiefe Kopie

In dieser Abbildung hat das MainObject1 Felder field1vom Typ int und ContainObject1vom Typ ContainObject. Wenn Sie eine tiefe Kopie von erstellen MainObject1, MainObject2wird mit field2dem kopierten Wert von field1und ContainObject2dem kopierten Wert von erstellt ContainObject1. Beachten Sie, dass Änderungen an ContainObject1in MainObject1nicht in berücksichtigt werden MainObject2.

guter Artikel


Es ist nicht deine Schuld, obwohl sich dieses Beispiel auf eine bezieht, field3die, wenn sie in der Lage ist, etwas so Tiefes wie dieses Problem zu verstehen, wo die Nummer 3 in diesem Beispiel stattfindet ContainObject2 .
Robb_2015

16

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.


12

'ShallowCopy' zeigt auf dieselbe Stelle im Speicher wie 'Source'. 'DeepCopy' zeigt auf eine andere Stelle im Speicher, aber der Inhalt ist der gleiche.


Dies ist leicht irreführend. Sowohl eine flache als auch eine tiefe Kopie kopieren das Objekt an einen neuen Speicherort. Eine tiefe kopiert auch die untergeordneten Objekte, während bei einer flachen Kopie nur die neuen Objekte auf die alten untergeordneten Objekte verweisen. Es ist schwer zu lesen, ohne sich auf das Originalobjekt zu beziehen.
Bill K

10

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.

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

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:

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

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.


8
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

Das ist kein gutes Beispiel. Flache Kopien werden meistens zum schnellen Kopieren von Objekten verwendet, ohne die Daten zu kopieren. Sobald ein Objekt die freigegebenen Daten ändern muss, wird eine tiefe Kopie davon erstellt. Ihr Beispiel wird wahrscheinlich Anfänger verwirren.
CMircea

Dies funktioniert nur in Sprachen, die Zeiger zur Darstellung von Zeichenfolgen verwenden. Der Punkt, den DHA anstrebt, ist, dass eine flache Kopie nur Zeiger auf den identischen (singulären) Originalinhalt dupliziert, während eine tiefe Kopie auch den referenzierten Inhalt der Zeiger klont. Beide Methoden kopieren den Oberflächeninhalt. Wenn die Sprache Zeichenfolgen als Oberflächenliteralinhalt speichert, z. B. in einem WAV-Header, funktioniert dieses Beispiel nicht. Beachten Sie, dass dies wahrscheinlich zu wählerisch für die meisten Probleme im wirklichen Leben ist, die nicht esoterisch sind.
DragonLord

8

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.


Dieser Link funktioniert leider nicht mehr - er verweist jetzt auf einen Artikel vom Februar 2019 zum Thema Webdesign (es sei denn, der Autor ist hellsichtig?).
PhilPhil

7

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.

Klon kopiert immer flach.

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 folgt-

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 am ursprünglichen Objekt spiegelt sich im flachen Objekt wider, nicht im tiefen Objekt.

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

OutPut- ViSuaLBaSiC C.


7

Ich möchte eher ein Beispiel als die 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 !!

Ich bekomme1 1 4 4 4 4 4 4
Suresh Prajapati

Führen Sie in Deep Copy copyObject.a = 8 aus und überprüfen Sie dann. Ich hoffe, Sie erhalten die richtige Antwort.
Vivek Mehta

5
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

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.


5

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

arr1 = arr2;   //shallow copy
arr1 = arr2.clone(); //deep copy

5

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.

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

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))

Geben Sie hier die Bildbeschreibung ein

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.

Geben Sie hier die Bildbeschreibung ein

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).

Geben Sie hier die Bildbeschreibung ein

Am Ende wird der Code gedruckt False , da y und z nicht dieselben Objekte sind.

HTH.


2

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.


2

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.


2

Um anderen Antworten mehr hinzuzufügen,

  • Eine flache Kopie eines Objekts führt eine Kopie nach Wert für auf Werttypen basierende Eigenschaften und eine Kopie nach Referenz für auf Referenztypen basierende Eigenschaften durch.
  • Eine Tiefenkopie eines Objekts führt eine kopierweise Wertschöpfung für auf Werttypen basierende Eigenschaften sowie eine kopierweise Wertschöpfung für auf Referenztypen basierende Eigenschaften tief in der Hierarchie (von Referenztypen) durch.

2

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.

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 + "]";
    }
}

1

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:

  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]);
    }

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.


Ich kenne keine anderen Sprachen, aber in C # / VB werden die Werte beim flachen Kopieren eines Arrays von Werttypen nicht kopiert. Die beiden Arrays beziehen sich auf dieselben Objekte. Fügen Sie einem Formular eine Schaltfläche hinzu und fügen Sie diesen Code hinzu, um 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]); }
Folgendes anzuzeigen

Sie haben Recht, ich habe meine Antwort genauer korrigiert und Klone auf Arrays verwendet. Sie haben absolut Recht, dass "das flache Kopieren eines Arrays von Werttypen die Werte nicht kopiert", die Verwendung des Klons für ein Array jedoch. Ich habe versucht, das zu erklären, versuche es. Danke
lukaszk

1

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.


0

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.

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

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 .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.