¿Cuál es la diferencia entre una copia profunda y una copia superficial?
language-agnostic
copy
deep-copy
shallow-copy
David Locke
fuente
fuente
Respuestas:
Las copias superficiales se duplican lo menos posible. Una copia superficial de una colección es una copia de la estructura de la colección, no los elementos. Con una copia superficial, dos colecciones ahora comparten los elementos individuales.
Las copias profundas duplican todo. Una copia profunda de una colección son dos colecciones con todos los elementos de la colección original duplicados.
fuente
Amplitud vs Profundidad; piense en términos de un árbol de referencias con su objeto como nodo raíz.
Superficial:
Las variables A y B se refieren a diferentes áreas de la memoria, cuando B se asigna a A, las dos variables se refieren a la misma área de la memoria. Las modificaciones posteriores a los contenidos de cualquiera se reflejan instantáneamente en los contenidos de otro, ya que comparten contenidos.
Profundo:
Las variables A y B se refieren a diferentes áreas de la memoria, cuando B se asigna a A, los valores en el área de memoria que A señala se copian en el área de memoria a la que B señala. Las modificaciones posteriores a los contenidos de cualquiera de ellas permanecen exclusivas de A o B; Los contenidos no se comparten.
fuente
En resumen, depende de qué puntos a qué. En una copia superficial, el objeto B apunta a la ubicación del objeto A en la memoria. En copia profunda, todas las cosas en la ubicación de la memoria del objeto A se copian en la ubicación de la memoria del objeto B.
Este artículo wiki tiene un gran diagrama.
http://en.wikipedia.org/wiki/Object_copy
fuente
Intenta considerar la siguiente imagen
Por ejemplo Object.MemberwiseClone crea un enlace de copia superficial
y usando la interfaz ICloneable puedes obtener una copia profunda como se describe aquí
fuente
Especialmente para desarrolladores de iOS:
Si
B
es una copia superficial deA
, entonces para datos primitivos es comoB = [A assign];
y para objetos es comoB = [A retain]
;B y A apuntan a la misma ubicación de memoria
Si
B
es una copia profunda deA
, entonces es comoB = [A copy];
B y A apuntan a diferentes ubicaciones de memoria
La dirección de memoria B es la misma que la de A
B tiene el mismo contenido que A
fuente
Copia superficial: copia los valores de los miembros de un objeto a otro.
Copia profunda: copia los valores de los miembros de un objeto a otro.
Cualquier objeto puntero se duplica y se copia en profundidad.
Ejemplo:
fuente
No he visto una respuesta corta y fácil de entender aquí, así que lo intentaré.
Con una copia superficial, cualquier destino señalado por el origen también lo señala el destino (de modo que no se copien objetos referenciados).
Con una copia profunda, cualquier objeto señalado por la fuente se copia y el destino señala la copia (por lo que ahora habrá 2 de cada objeto referenciado). Esto recurre hacia abajo el árbol de objetos.
fuente
Solo en aras de una fácil comprensión, puede seguir este artículo: https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm
Copia superficial:
Copia profunda:
fuente
{Imagina dos objetos: A y B del mismo tipo _t (con respecto a C ++) y estás pensando en copiar de forma superficial / profunda A a B}
Copia superficial: simplemente hace una copia de la referencia a A en B. Piense en ello como una copia de la dirección de A. Por lo tanto, las direcciones de A y B serán las mismas, es decir, apuntarán a la misma ubicación de memoria, es decir, el contenido de los datos.
Copia profunda: simplemente hace una copia de todos los miembros de A, asigna memoria en una ubicación diferente para B y luego asigna los miembros copiados a B para lograr una copia profunda. De esta manera, si A se vuelve no existente, B sigue siendo válido en la memoria. El término correcto para usar sería clonación, donde sabe que ambos son totalmente iguales, pero diferentes (es decir, almacenados como dos entidades diferentes en el espacio de la memoria). También puede proporcionar su envoltorio de clonación donde puede decidir mediante la lista de inclusión / exclusión qué propiedades seleccionar durante la copia profunda. Esta es una práctica bastante común cuando creas API.
Puede optar por hacer una copia superficial SOLAMENTE_Si comprende las apuestas involucradas. Cuando tiene una enorme cantidad de punteros para tratar en C ++ o C, hacer una copia superficial de un objeto es REALMENTE una mala idea.
EJEMPLO_DE_ COPIA PROFUNDA_ Un ejemplo es que, cuando intenta realizar un procesamiento de imágenes y reconocimiento de objetos, necesita enmascarar el "Movimiento irrelevante y repetitivo" de las áreas de procesamiento. Si está utilizando punteros de imagen, es posible que tenga la especificación para guardar esas imágenes de máscara. AHORA ... si hace una copia superficial de la imagen, cuando las referencias del puntero se matan de la pila, perdió la referencia y su copia, es decir, habrá un error de tiempo de ejecución de violación de acceso en algún momento. En este caso, lo que necesita es una copia profunda de su imagen CLONANDO. De esta forma, puede recuperar las máscaras en caso de que las necesite en el futuro.
EXAMPLE_OF_SHALLOW_COPY No tengo mucho conocimiento en comparación con los usuarios de StackOverflow, así que siéntase libre de eliminar esta parte y poner un buen ejemplo si puede aclarar. Pero realmente creo que no es una buena idea hacer una copia superficial si sabe que su programa se ejecutará durante un período infinito de tiempo, es decir, la operación continua "push-pop" sobre la pila con llamadas a funciones. Si está demostrando algo a una persona aficionada o novata (p. Ej., Tutoriales de C / C ++), entonces probablemente esté bien. Pero si está ejecutando una aplicación como el sistema de vigilancia y detección, o el Sistema de seguimiento de sonda, se supone que no debe seguir copiando superficialmente sus objetos porque matará su programa tarde o temprano.
fuente
'ShallowCopy' apunta a la misma ubicación en la memoria que lo hace 'Source'. 'DeepCopy' apunta a una ubicación diferente en la memoria, pero el contenido es el mismo.
fuente
¿Qué es la copia superficial?
La copia superficial es una copia en bits de un objeto. Se crea un nuevo objeto que tiene una copia exacta de los valores en el objeto original. Si alguno de los campos del objeto son referencias a otros objetos, solo se copian las direcciones de referencia, es decir, solo se copia la dirección de memoria.
En esta figura,
MainObject1
tiene camposfield1
de tipo int yContainObject1
de tipoContainObject
. Cuando hace una copia superficial deMainObject1
,MainObject2
se crea confield2
el valor copiado defield1
y aún apuntando aContainObject1
sí mismo. Tenga en cuenta que dado quefield1
es de tipo primitivo, su valor se copiafield2
pero, dado queContainedObject1
es un objeto,MainObject2
todavía apunta aContainObject1
. Por lo tanto, cualquier cambio realizado enContainObject1
inMainObject1
se reflejará enMainObject2
.Ahora, si esta es una copia superficial, veamos qué es una copia profunda.
¿Qué es la copia profunda?
Una copia profunda copia todos los campos y hace copias de la memoria asignada dinámicamente señalada por los campos. Se produce una copia profunda cuando se copia un objeto junto con los objetos a los que se refiere.
En esta figura, MainObject1 tiene campos
field1
de tipo int yContainObject1
de tipoContainObject
. Cuando realiza una copia profunda deMainObject1
,MainObject2
se crea con elfield2
contenido copiado defield1
yContainObject2
el valor copiado deContainObject1
. Tenga en cuenta que cualquier cambio realizado enContainObject1
inMainObject1
no se reflejará enMainObject2
.buen artículo
fuente
field3
que cuando está en condiciones de tratar de comprender algo tan profundo como ese problema, ¿dónde está teniendo lugar el # 3 en ese ejemploContainObject2
?En la programación orientada a objetos, un tipo incluye una colección de campos miembros. Estos campos pueden almacenarse por valor o por referencia (es decir, un puntero a un valor).
En una copia superficial, se crea una nueva instancia del tipo y los valores se copian en la nueva instancia. Los punteros de referencia también se copian al igual que los valores. Por lo tanto, las referencias apuntan a los objetos originales. Cualquier cambio en los miembros que se almacenan por referencia aparece tanto en el original como en la copia, ya que no se realizó ninguna copia del objeto referenciado.
En una copia profunda, los campos que se almacenan por valor se copian como antes, pero los punteros a los objetos almacenados por referencia no se copian. En cambio, se realiza una copia profunda del objeto referenciado y se almacena un puntero al nuevo objeto. Cualquier cambio que se realice en esos objetos referenciados no afectará a otras copias del objeto.
fuente
'ShallowCopy' apunta a la misma ubicación en la memoria que lo hace 'Source'. 'DeepCopy' apunta a una ubicación diferente en la memoria, pero el contenido es el mismo.
fuente
Clonación superficial:
Definición: "Una copia superficial de un objeto copia el objeto 'principal', pero no copia los objetos internos". Cuando un objeto personalizado (p. Ej., Empleado) tiene solo variables primitivas de tipo Cadena, entonces utiliza la clonación superficial.
Volverá
super.clone();
en el método clone () sustituido y su trabajo ha terminado.Clonación profunda :
Definición: "A diferencia de la copia superficial, una copia profunda es una copia totalmente independiente de un objeto".
Significa cuando un objeto Empleado contiene otro objeto personalizado:
Luego debe escribir el código para clonar el objeto 'Dirección' también en el método clone () anulado. De lo contrario, el objeto Dirección no se clonará y provocará un error cuando cambie el valor de Dirección en el objeto Empleado clonado, que también refleja el original.
fuente
fuente
Copia profunda
Una copia profunda copia todos los campos y hace copias de la memoria asignada dinámicamente señalada por los campos. Se produce una copia profunda cuando se copia un objeto junto con los objetos a los que se refiere.
Copia superficial
La copia superficial es una copia en bits de un objeto. Se crea un nuevo objeto que tiene una copia exacta de los valores en el objeto original. Si alguno de los campos del objeto son referencias a otros objetos, solo se copian las direcciones de referencia, es decir, solo se copia la dirección de memoria.
fuente
Copia superficial : la variable de referencia dentro de los objetos originales y los copiados superficialmente hacen referencia a objetos comunes .
Copia profunda : la variable de referencia dentro de los objetos originales y los copiados en profundidad tienen referencia a diferentes objetos.
la clase principal está siguiendo
La salida de arriba será-
Cualquier cambio realizado en el objeto original se reflejará en un objeto poco profundo, no en un objeto profundo.
Salida - ViSuaLBaSiC C
fuente
Me gustaría dar un ejemplo en lugar de la definición formal.
Este código muestra una copia superficial :
Este código muestra una copia profunda :
fuente
1 1 4 4 4 4 4 4
fuente
En términos simples, una copia superficial es similar a Call By Reference y una copia profunda es similar a Call By Value
En Llamada por referencia, los parámetros formales y reales de una función se refieren a la misma ubicación de memoria y al valor.
En Call By Value, los parámetros formales y reales de una función se refieren a diferentes ubicaciones de memoria pero que tienen el mismo valor.
fuente
Imagine que hay dos matrices llamadas arr1 y arr2.
fuente
Una copia superficial construye un nuevo objeto compuesto e inserta sus referencias en él al objeto original.
A diferencia de la copia superficial, la copia profunda construye un nuevo objeto compuesto y también inserta copias de los objetos originales del objeto compuesto original.
Tomemos un ejemplo.
El código anterior imprime FALSO.
A ver cómo.
Objeto compuesto original
x=[1,[2]]
(llamado como compuesto porque tiene un objeto dentro del objeto (Inicio))Como puede ver en la imagen, hay una lista dentro de la lista.
Luego creamos una copia superficial usando
y = copy.copy(x)
. Lo que hace Python aquí es crear un nuevo objeto compuesto, pero los objetos dentro de ellos apuntan a los objetos originales.En la imagen ha creado una nueva copia para la lista externa. pero la lista interna sigue siendo la misma que la original.
Ahora creamos una copia profunda de la misma usando
z = copy.deepcopy(x)
. lo que hace python aquí es crear un nuevo objeto para la lista externa así como para la lista interna. como se muestra en la imagen a continuación (resaltada en rojo).Al final se imprime el código
False
, ya que y y z no son los mismos objetos.HTH
fuente
La copia superficial es crear un nuevo objeto y luego copiar los campos no estáticos del objeto actual al nuevo objeto. Si un campo es un tipo de valor -> se realiza una copia bit a bit del campo; para un tipo de referencia -> la referencia se copia pero el objeto referido no; por lo tanto, el objeto original y su clon se refieren al mismo objeto.
La copia profunda crea un nuevo objeto y luego copia los campos no estáticos del objeto actual en el nuevo objeto. Si un campo es un tipo de valor -> se realiza una copia bit a bit del campo. Si un campo es un tipo de referencia -> se realiza una nueva copia del objeto referido. Las clases que se van a clonar se deben marcar como [Serializable].
fuente
Tomado de [blog]: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
La copia profunda implica el uso del contenido de un objeto para crear otra instancia de la misma clase. En una copia profunda, los dos objetos pueden contener la misma información, pero el objeto de destino tendrá sus propios almacenamientos intermedios y recursos. La destrucción de cualquiera de los objetos no afectará al objeto restante. El operador de asignación sobrecargado crearía una copia profunda de los objetos.
La copia superficial implica copiar el contenido de un objeto en otra instancia de la misma clase, creando así una imagen espejo. Debido a la copia directa de referencias y punteros, los dos objetos compartirán el mismo contenido contenido externamente del otro objeto para que sea impredecible.
Explicación:
Usando un constructor de copia simplemente copiamos los valores de datos miembro por miembro. Este método de copia se llama copia superficial. Si el objeto es una clase simple, compuesta de tipos integrados y sin punteros, esto sería aceptable. Esta función usaría los valores y los objetos y su comportamiento no se alteraría con una copia superficial, solo se copiarán las direcciones de los punteros que son miembros y no el valor al que apunta la dirección. Los valores de datos del objeto serían alterados inadvertidamente por la función. Cuando la función se sale del alcance, la copia del objeto con todos sus datos se saca de la pila.
Si el objeto tiene punteros, se debe ejecutar una copia profunda. Con la copia profunda de un objeto, se asigna memoria para el objeto en la tienda libre y se copian los elementos apuntados. Se usa una copia profunda para los objetos que se devuelven de una función.
fuente
Para agregar más a otras respuestas,
fuente
La copia superficial no creará una nueva referencia, pero la copia profunda creará la nueva referencia.
Aquí está el programa para explicar la copia profunda y superficial.
fuente
Copiar ararys:
La matriz es una clase, lo que significa que es un tipo de referencia, por lo que matriz1 = matriz2 da como resultado dos variables que hacen referencia a la misma matriz.
Pero mira este ejemplo:
clon superficial significa que solo se copia la memoria representada por la matriz clonada.
Si la matriz contiene objetos de tipo de valor, los valores se copian ;
si la matriz contiene un tipo de referencia, solo se copian las referencias, por lo que hay dos matrices cuyos miembros hacen referencia a los mismos objetos .
Para crear una copia profunda, donde el tipo de referencia está duplicado, debe recorrer la matriz y clonar cada elemento manualmente.
fuente
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]); }
Llegué a entender de las siguientes líneas.
La copia superficial copia un campo de tipo de valor de objeto (int, float, bool) en el objeto de destino y los tipos de referencia del objeto (cadena, clase, etc.) se copian como referencias en el objeto de destino. En este objetivo, los tipos de referencia apuntarán a la ubicación de la memoria del objeto fuente.
Copia profunda copia el valor de un objeto y los tipos de referencia en una nueva copia completa de los objetos de destino. Esto significa que tanto a los tipos de valor como a los tipos de referencia se les asignarán nuevas ubicaciones de memoria.
fuente
Agregando a todas las definiciones anteriores, una copia profunda más y más comúnmente utilizada, está en el constructor de copia (u opcionador de asignación de sobrecarga) de la clase.
Copia superficial -> es cuando no proporciona un constructor de copia. Aquí, solo se copia el objeto, pero no todos los miembros de la clase se copian.
Copia profunda -> es cuando ha decidido implementar el constructor de copia o la asignación de sobrecarga en su clase y permite copiar a todos los miembros de la clase.
fuente
El constructor de copia se usa para inicializar el nuevo objeto con el objeto creado previamente de la misma clase. Por defecto, el compilador escribió una copia superficial. La copia superficial funciona bien cuando la asignación de memoria dinámica no está involucrada porque cuando la asignación de memoria dinámica está involucrada, ambos objetos apuntarán hacia la misma ubicación de memoria en un montón, por lo tanto, para eliminar este problema, escribimos una copia profunda para que ambos objetos tengan su propia copia de atributos en un recuerdo Para leer los detalles con ejemplos completos y explicaciones, puede ver el artículo Constructores de C ++ .
fuente