c++ - shallow - deep copy java
Copia profunda vs copia superficial (3)
Posible duplicado:
¿Cuál es la diferencia entre una copia profunda y una copia superficial?
¿Cuál es la diferencia entre una copia profunda y superficial? ¿Qué tipo de copia hace un constructor de copia?
El ejemplo por excelencia de esto es una serie de punteros a estructuras u objetos (que son mutables).
Una copia superficial copia la matriz y mantiene referencias a los objetos originales.
Una copia profunda también copiará (clonará) los objetos para que no tengan relación con el original. Implícito en esto es que el objeto mismo está profundamente copiado. Aquí es donde se pone difícil porque no hay forma real de saber si algo fue copiado profundamente o no.
El constructor de copia se utiliza para iniciar el nuevo objeto con el objeto previamente creado 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 se trata de asignación de memoria dinámica, ambos apuntan hacia la misma ubicación de memoria en un montón. Por lo tanto, para eliminar este problema escribimos 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 y destructores .
El constructor de copia predeterminado es superficial. Puede hacer que sus propios constructores de copia sean profundos o superficiales, según corresponda. Ver notas de C ++: OOP: Copiar constructores .
La copia profunda literalmente realiza una copia profunda. Significa que si su clase tiene algunos campos que son referencias, sus valores serán copiados, no referencias ellos mismos. Si, por ejemplo, tiene dos instancias de una clase, A y B con campos de tipo de referencia, y realiza una copia profunda, cambiar un valor de ese campo en A no afectará un valor en B. Y viceversa. Las cosas son diferentes con una copia superficial, porque solo se copian las referencias, por lo tanto, cambiar este campo en un objeto copiado afectaría al objeto original.
¿Qué tipo de copia hace un constructor de copia?
Depende de la implementación. Esto significa que no existen reglas estrictas al respecto, puede implementarlo como una copia profunda o superficial, sin embargo, hasta donde sé, es una práctica común implementar una copia profunda en un constructor de copia. Sin embargo, un constructor de copia predeterminado realiza una copia superficial.
Copia superficial:
Algunos miembros de la copia pueden hacer referencia a los mismos objetos que el original:
class X
{
private:
int i;
int *pi;
public:
X()
: pi(new int)
{ }
X(const X& copy) // <-- copy ctor
: i(copy.i), pi(copy.pi)
{ }
};
Aquí, el miembro pi
del objeto X
original y copiado apuntará al mismo int
.
Copia profunda
Todos los miembros del original se clonan (recursivamente, si es necesario). No hay objetos compartidos
class X
{
private:
int i;
int *pi;
public:
X()
: pi(new int)
{ }
X(const X& copy) // <-- copy ctor
: i(copy.i), pi(new int(*copy.pi)) // <-- note this line in particular!
{ }
};
Aquí, el miembro pi
del objeto X
original y copiado apuntará a diferentes objetos int
, pero ambos tienen el mismo valor.
El constructor de copia predeterminado (que se proporciona automáticamente si no proporciona uno) crea solo copias superficiales.
Corrección: Varios comentarios a continuación han señalado correctamente que es incorrecto decir que el constructor de copia predeterminado siempre realiza una copia superficial (o una copia profunda, para el caso). Si el constructor de copias de un tipo crea una copia superficial, o una copia profunda, o algo intermedio , depende de la combinación del comportamiento de copia de cada miembro; Después de todo, se puede hacer que un constructor de copias de un miembro haga lo que quiera.
Esto es lo que dice la sección 12.8, párrafo 8 de la norma C ++ de 1998 sobre los ejemplos de código anteriores:
El constructor de copia implícitamente definido para la clase
X
realiza una copia de sus subobjetos en forma de miembro. [...] Cada subobjeto se copia de la manera apropiada para su tipo: [...] [I] f el subobjeto es de tipo escalar, se usa el operador de asignación incorporada.