ITA - Appunti Cpp 016 - Shallow and Deep Copy
September 2024 (674 Words, 4 Minutes)
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:
- shallow copy
- deep copy.
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:
- Il copy constructor copia il valore del puntatore dati da altro.dati a dati, ma entrambi i puntatori finiscono per puntare alla stessa area di memoria.
- Quando uno dei due oggetti (altro o la copia) viene distrutto, l’area di memoria puntata da dati viene deallocata.
- Se successivamente anche l’altro oggetto viene distrutto, si tenta di deallocare di nuovo la stessa memoria, causando un errore (doppia deallocazione) o altri comportamenti imprevisti.
Problemi della Shallow Copy
I principali problemi che possono sorgere da una shallow copy sono:
- Doppia deallocazione: Se entrambi gli oggetti (originale e copia) cercano di liberare la stessa memoria, si può verificare un errore di esecuzione.
- Accesso concorrente: Modificare i dati attraverso un oggetto può inaspettatamente influenzare l’altro oggetto, poiché condividono la stessa area di memoria.
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:
- Il copy constructor alloca una nuova area di memoria per dati nel nuovo oggetto, anziché copiare semplicemente l’indirizzo del puntatore.
- I dati dell’oggetto originale vengono copiati uno per uno nell’area di memoria appena allocata.
- Ogni oggetto (altro e la copia) gestisce la propria area di memoria indipendente, prevenendo i problemi associati alla shallow copy.
Vantaggi della Deep Copy
I principali vantaggi della deep copy rispetto alla shallow copy sono:
- Indipendenza della memoria: Ogni oggetto copia possiede la propria area di memoria, il che elimina il rischio di doppia deallocazione o accesso concorrente alla stessa area di memoria.
- Isolamento delle modifiche: Le modifiche effettuate su un oggetto non influenzano gli altri oggetti, poiché ogni oggetto gestisce una copia separata dei dati.
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
- geeksforgeeks.org - shallow copy and deep copy in c/
- learncpp.com - shallow vs deep copying
- owlcation.com - Copy Constructor shallow copy vs deep copy
Quest'opera è distribuita con Licenza Creative Commons Attribuzione - Condividi allo stesso modo 4.0 Internazionale Theme Moonwalk