Home

ITA - Appunti Cpp 016 - Shallow and Deep Copy

linux cpp

Il copy constructor è utilizzato per creare un nuovo oggetto come copia di un oggetto esistente. Esistono due tipi di copia che il copy constructor può effettuare:

Cos’è una Shallow Copy?

Una shallow copy (copia superficiale) è una copia di un oggetto in cui vengono copiati solo i valori dei membri di dati dell’oggetto originale. Tuttavia, se l’oggetto contiene puntatori a memoria dinamica, la shallow copy copierà solo l’indirizzo di memoria puntato, non l’effettivo contenuto. Di conseguenza, sia l’oggetto originale sia la copia condividono la stessa area di memoria, il che può portare a problemi, come doppie deallocazioni o accessi concorrenti alla stessa memoria.

Esempio di Shallow Copy nel Copy Constructor


class Array {
public:
    int* dati;
    int dimensione;

    // Costruttore
    Array(int dim) : dimensione(dim) {
        dati = new int[dimensione];
    }

    // Copy constructor che effettua una shallow copy
    Array(const Array& altro) : dimensione(altro.dimensione) {
        dati = altro.dati; // Shallow copy: copia solo il puntatore, non i dati a cui punta
    }

    ~Array() {
        delete[] dati; // Possibile problema: doppia deallocazione!
    }
};

In questo esempio:

Problemi della Shallow Copy

I principali problemi che possono sorgere da una shallow copy sono:

Cos’è una Deep Copy?

Una deep copy (copia profonda) è una copia di un oggetto in cui non solo i valori dei membri di dati vengono copiati, ma viene anche allocata una nuova area di memoria per contenere i dati puntati dai membri puntatore. In questo modo, l’oggetto copia possiede una propria copia indipendente dei dati originali, eliminando i problemi di condivisione della stessa memoria tra l’oggetto originale e la copia.

Esempio di Deep Copy nel Copy Constructor


class Array {
public:
    int* dati;
    int dimensione;

    // Costruttore
    Array(int dim) : dimensione(dim) {
        dati = new int[dimensione];
    }

    // Copy constructor che effettua una deep copy
    Array(const Array& altro) : dimensione(altro.dimensione) {
        dati = new int[dimensione]; // Allocazione di nuova memoria
        for (int i = 0; i < dimensione; ++i) {
            dati[i] = altro.dati[i]; // Copia effettiva dei dati
        }
    }

    ~Array() {
        delete[] dati; // Deallocazione della memoria
    }
};

In questo esempio:

Vantaggi della Deep Copy

I principali vantaggi della deep copy rispetto alla shallow copy sono:

Quando Usare la Deep Copy?

La deep copy è particolarmente importante quando la classe gestisce risorse che non dovrebbero essere condivise tra oggetti, come memoria dinamica, file handle, o connessioni di rete. Implementando una deep copy nel copy constructor, garantisci che ogni oggetto possa essere gestito in modo sicuro e indipendente dagli altri.

Riferimenti