Copia superficial y copia profunda en C++

En general, crear una copia de un objeto significa crear una réplica exacta del objeto que tenga el mismo valor literal, tipo de datos y recursos.

// Copiar Constructor
Geeks Obj1(Obj);
o
Geeks Obj1 = Obj;

// Operador de asignación predeterminado
Geeks Obj2;
Obj2 = Obj1;

Dependiendo de los recursos como la memoria dinámica que tiene el objeto, necesitamos realizar una copia superficial o una copia profunda para crear una réplica del objeto. En general, si las variables de un objeto se han asignado dinámicamente, se requiere hacer una copia profunda para crear una copia del objeto.

Copia superficial :

En copia superficial, se crea un objeto simplemente copiando los datos de todas las variables del objeto original. Esto funciona bien si ninguna de las variables del objeto está definida en la sección de almacenamiento dinámico de la memoria . Si algunas variables se asignan dinámicamente a la memoria desde la sección del montón, entonces la variable del objeto copiado también hará referencia a la misma ubicación de memoria.
Esto creará ambigüedad y errores de tiempo de ejecución, puntero colgante. Dado que ambos objetos harán referencia a la misma ubicación de memoria, el cambio realizado por uno también reflejará esos cambios en otro objeto. Dado que queríamos crear una réplica del objeto, la copia superficial no cumplirá este propósito. 
Nota: el compilador de C++ crea implícitamente un constructor de copia ysobrecarga el operador de asignación para realizar una copia superficial en tiempo de compilación.
 

Copia superficial del objeto si algunas variables están definidas en la memoria del montón, entonces:

A continuación se muestra la implementación del enfoque anterior:

C++

// C++ program for the above approach
#include <iostream>
using namespace std;
 
// Box Class
class box {
private:
    int length;
    int breadth;
    int height;
 
public:
    // Function that sets the dimensions
    void set_dimensions(int length1, int breadth1,
                        int height1)
    {
        length = length1;
        breadth = breadth1;
        height = height1;
    }
 
    // Function to display the dimensions
    // of the Box object
    void show_data()
    {
        cout << " Length = " << length
             << "\n Breadth = " << breadth
             << "\n Height = " << height
             << endl;
    }
};
 
// Driver Code
int main()
{
    // Object of class Box
    box B1, B3;
 
    // Set dimensions of Box B1
    B1.set_dimensions(14, 12, 16);
    B1.show_data();
 
    // When copying the data of object
    // at the time of initialization
    // then copy is made through
    // COPY CONSTRUCTOR
    box B2 = B1;
    B2.show_data();
 
    // When copying the data of object
    // after initialization then the
    // copy is done through DEFAULT
    // ASSIGNMENT OPERATOR
    B3 = B1;
    B3.show_data();
 
    return 0;
}
Producción:

Length = 14
 Breadth = 12
 Height = 16
 Length = 14
 Breadth = 12
 Height = 16
 Length = 14
 Breadth = 12
 Height = 16

Copia profunda :

En Deep copy, un objeto se crea copiando datos de todas las variables y también asigna recursos de memoria similares con el mismo valor al objeto. Para realizar una copia profunda, debemos definir explícitamente el constructor de copia y asignar también memoria dinámica, si es necesario. Además, también se requiere asignar memoria dinámicamente a las variables en los otros constructores.

A continuación se muestra la implementación del enfoque anterior:

C++

// C++ program to implement the
// deep copy
#include <iostream>
using namespace std;
 
// Box Class
class box {
private:
    int length;
    int* breadth;
    int height;
 
public:
    // Constructor
    box()
    {
        breadth = new int;
    }
 
    // Function to set the dimensions
    // of the Box
    void set_dimension(int len, int brea,
                       int heig)
    {
        length = len;
        *breadth = brea;
        height = heig;
    }
 
    // Function to show the dimensions
    // of the Box
    void show_data()
    {
        cout << " Length = " << length
             << "\n Breadth = " << *breadth
             << "\n Height = " << height
             << endl;
    }
 
    // Parameterized Constructors for
    // for implementing deep copy
    box(box& sample)
    {
        length = sample.length;
        breadth = new int;
        *breadth = *(sample.breadth);
        height = sample.height;
    }
 
    // Destructors
    ~box()
    {
        delete breadth;
    }
};
 
// Driver Code
int main()
{
    // Object of class first
    box first;
 
    // Set the dimensions
    first.set_dimension(12, 14, 16);
 
    // Display the dimensions
    first.show_data();
 
    // When the data will be copied then
    // all the resources will also get
    // allocated to the new object
    box second = first;
 
    // Display the dimensions
    second.show_data();
 
    return 0;
}
Producción:

Length = 12
 Breadth = 14
 Height = 16
 Length = 12
 Breadth = 14
 Height = 16

Veamos las diferencias en forma tabular -:

  Copia superficial  Copia profunda
1. Cuando creamos una copia de un objeto copiando datos de todas las variables miembro tal como están, se denomina copia superficial.  Cuando creamos un objeto copiando datos de otro objeto junto con los valores de los recursos de memoria que residen fuera del objeto, se denomina copia profunda.
2. Una copia superficial de un objeto copia todos los valores de los campos de miembros.  La copia profunda se realiza implementando nuestro propio constructor de copias.
3. En copia superficial, los dos objetos no son independientes. Copia todos los campos y hace copias de la memoria asignada dinámicamente a la que apuntan los campos.
4. También crea una copia de los objetos asignados dinámicamente. Si no creamos la copia profunda de manera correcta, la copia apuntará al original, con consecuencias desastrosas.

Publicación traducida automáticamente

Artículo escrito por nichil942singh y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *