Question Quelle est la différence entre une copie profonde et une copie superficielle?


Quelle est la différence entre une copie profonde et une copie superficielle?


755
2017-10-08 20:22


origine


Réponses:


Les copies peu profondes reproduisent le moins possible. Une copie superficielle d'une collection est une copie de la structure de collection, pas les éléments. Avec une copie superficielle, deux collections partagent maintenant les éléments individuels.

Des copies profondes dupliquent tout. Une copie profonde d'une collection est deux collections avec tous les éléments de la collection originale dupliqués.


592
2017-10-08 20:29



Largeur par rapport à la profondeur; Pensez en termes d'arbre de références avec votre objet en tant que nœud racine.

Peu profond:

Before Copy Shallow Copying Shallow Done

Les variables A et B se rapportent à différentes zones de mémoire, lorsque B est assigné à A, les deux variables se réfèrent à la même zone de mémoire. Les modifications ultérieures au contenu de l'une ou de l'autre sont immédiatement répercutées dans le contenu de l'autre, car elles partagent le contenu.

Profond:

Before Copy Deep Copying Deep Done

Les variables A et B se rapportent à différentes zones de mémoire, lorsque B est attribué à A, les valeurs dans la zone de mémoire sur lesquelles A pointe sont copiées dans la zone de mémoire sur laquelle B pointe. Les modifications ultérieures au contenu de l'un ou l'autre demeurent uniques à A ou à B; le contenu n'est pas partagé.


711
2017-10-08 20:39



En bref, cela dépend de ce qui indique quoi. Dans une copie superficielle, l'objet B pointe vers l'emplacement de l'objet A en mémoire. En copie profonde, toutes les choses dans l'emplacement mémoire de l'objet A sont copiées dans l'emplacement mémoire de l'objet B.

Cet article wiki a un grand diagramme.

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


135
2017-10-08 20:24



Surtout pour les développeurs iOS: 

Si B est un copie superficielle de A, alors pour les données primitives, c'est comme B = [A assign]; et pour les objets c'est comme B = [A retain];

B et A pointent vers le même emplacement de mémoire

Si B est un copie profonde de Aalors c'est comme B = [A copy];

B et A pointent vers différents emplacements de mémoire

L'adresse mémoire B est la même que celle de A

B a le même contenu que A


68
2018-01-23 11:43



Copie superficielle: Copie les valeurs des membres d'un objet dans un autre.

Copie profonde: Copie les valeurs des membres d'un objet dans un autre.
Tous les objets de pointeur sont dupliqués et copiés en profondeur.

Exemple:

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

54
2017-10-08 20:25



Essayez de considérer l'image suivante

enter image description here

Par exemple Object.MemberwiseClone crée un peu profond copie lien

et en utilisant ICloneable interface que vous pouvez obtenir Profond copier comme décrit ici


51
2018-06-15 08:42



Je n'ai pas vu une réponse courte, facile à comprendre ici - donc je vais essayer.

Avec une copie superficielle, tout objet pointé par la source est également pointé par la destination (de sorte qu'aucun objet référencé n'est copié).

Avec une copie profonde, tout objet pointé par la source est copié et la copie est pointée par la destination (il y aura donc 2 de chaque objet référencé). Cela récursive dans l'arborescence des objets.


40
2017-10-08 20:36



{Imaginez deux objets: A et B de même type _t (par rapport à C ++) et vous pensez à la copie superficielle / profonde A à B}

Copie superficielle: Faites simplement une copie de la référence à A dans B. Pensez-y comme une copie de l'adresse de A. Ainsi, les adresses de A et B seront les mêmes, c'est-à-dire qu'elles pointeront vers le même emplacement de mémoire, c'est-à-dire le contenu des données.

Copie profonde: Il suffit de faire une copie de tous les membres de A, d'allouer de la mémoire dans un emplacement différent pour B, puis d'affecter les membres copiés à B pour obtenir une copie en profondeur. De cette façon, si A devient inexistant, B est toujours valide dans la mémoire. Le terme correct à utiliser serait le clonage, où vous savez qu'ils sont tous les deux totalement identiques, mais néanmoins différents (c'est-à-dire stockés comme deux entités différentes dans l'espace mémoire). Vous pouvez également fournir votre wrapper de clone où vous pouvez décider via la liste d'inclusion / exclusion les propriétés à sélectionner lors d'une copie en profondeur. C'est une pratique courante lorsque vous créez des API.

Vous pouvez choisir de faire une copie peu profonde SEULEMENT SI vous comprenez les enjeux impliqués. Lorsque vous avez un nombre énorme de pointeurs à traiter en C ++ ou C, faire une copie superficielle d'un objet est VRAIMENT Une mauvaise idée.

EXAMPLE_OF_DEEP COPY_ Par exemple, lorsque vous essayez d'effectuer le traitement d'image et la reconnaissance d'objet, vous devez masquer les "mouvements non significatifs et répétitifs" hors de vos zones de traitement. Si vous utilisez des pointeurs d'image, vous pouvez avoir la spécification pour enregistrer ces images de masque. MAINTENANT ... si vous faites une copie superficielle de l'image, lorsque les références du pointeur sont TUES dans la pile, vous perdez la référence et sa copie, c'est-à-dire qu'il y aura une erreur d'exécution à un moment donné. Dans ce cas, vous avez besoin d'une copie en profondeur de votre image en la CLONANT. De cette façon, vous pouvez récupérer les masques au cas où vous en auriez besoin dans le futur.

EXAMPLE_OF_SHALLOW_COPY Je ne suis pas très bien informé par rapport aux utilisateurs de StackOverflow alors n'hésitez pas à supprimer cette partie et à mettre un bon exemple si vous pouvez clarifier. Mais je pense vraiment que ce n'est pas une bonne idée de faire une copie superficielle si vous savez que votre programme va fonctionner pendant une période de temps infinie, c'est-à-dire une opération "push-pop" continue sur la pile avec des appels de fonction. Si vous démontrez quelque chose à un amateur ou à une personne novice (par exemple, un tutoriel en C / C ++), alors c'est probablement correct. Mais si vous utilisez une application telle que le système de surveillance et de détection, ou le système de suivi Sonar, vous n'êtes pas censé garder votre objet en copie superficielle, car il va tuer votre programme tôt ou tard.


32
2018-01-31 23:39



Juste pour faciliter la compréhension, vous pouvez suivre cet article: https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm


Copie superficielle:

Shallow Copy 


Copie profonde:

Deep Copy


28
2018-03-19 06:15



char * Source = "Hello, world.";

char * ShallowCopy = Source;    

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

'ShallowCopy' pointe vers le même emplacement en mémoire que 'Source'. 'DeepCopy' pointe vers un emplacement différent en mémoire, mais le contenu est le même.


27
2017-10-08 20:32



Qu'est-ce que Shallow Copy?

La copie peu profonde est une copie peu sage d'un objet. Un nouvel objet est créé avec une copie exacte des valeurs de l'objet d'origine. Si l'un des champs de l'objet est une référence à d'autres objets, seules les adresses de référence sont copiées, c'est-à-dire que seule l'adresse de mémoire est copiée. Shallow Copy

Dans cette figure, le MainObject1 a des champs field1 de type int, et ContainObject1 de type ContainObject. Lorsque vous faites une copie superficielle de MainObject1, MainObject2 est créé avec field2 contenant la valeur copiée de field1 et toujours en montrant ContainObject1 lui-même. Notez que depuis field1 est de type primitif, sa valeur est copiée field2 mais depuis ContainedObject1 est un objet, MainObject2 pointe toujours vers ContainObject1. Donc, tout changement apporté à ContainObject1 dans MainObject1 sera reflété dans MainObject2.

Maintenant, si c'est une copie superficielle, permet de voir quelle est la copie profonde?

Qu'est-ce que Deep Copy?

Une copie complète copie tous les champs et effectue des copies de la mémoire allouée dynamiquement désignée par les champs. Une copie profonde se produit lorsqu'un objet est copié avec les objets auxquels il se réfère. Deep Copy

Dans cette figure, le MainObject1 a des champs field1 de type int, et ContainObject1 de type ContainObject. Lorsque vous faites une copie profonde de MainObject1, MainObject2 est créé avec field2 contenant la valeur copiée de field1 et ContainObject2 contenant la valeur copiée de ContainObject1. Notez les modifications apportées à ContainObject1 dans MainObject1 ne reflétera pas dans MainObject2.

bon article


18
2017-12-18 06:55