Regola del tre: se una classe gestisce una risorsa (ad esempio, memoria), allora se si implementa esplicitamente uno dei seguenti metodi, è necessario implementare anche gli altri:
C++11: Regola del cinque – sono state aggiunte operazioni di spostamento:
La violazione di questa regola porta a errori nella gestione delle risorse, come la doppia eliminazione o perdite di memoria.
class Buffer { char* data; public: Buffer(size_t sz) : data(new char[sz]) {} ~Buffer() { delete[] data; } Buffer(const Buffer& other) : data(new char[strlen(other.data)+1]) { strcpy(data, other.data); } Buffer& operator=(const Buffer& other) { if (&other != this) { delete[] data; data = new char[strlen(other.data)+1]; strcpy(data, other.data); } return *this; } // semantica di spostamento in C++11+: Buffer(Buffer&& other) noexcept : data(other.data) { other.data = nullptr; } Buffer& operator=(Buffer&& other) noexcept { if (&other != this) { delete[] data; data = other.data; other.data = nullptr; } return *this; } };
È sufficiente implementare solo il distruttore se la classe gestisce un puntatore?
No. Senza le operazioni di copia e spostamento, quando si copia, si verificherà una doppia eliminazione della memoria. Ad esempio:
Buffer a(10); Buffer b = a; // b e a elimineranno lo stesso puntatore!
Storia
Nella piattaforma di aggregazione dei dati per le telecomunicazioni, tutte le classi implementavano solo il distruttore. Dopo la refactoring della struttura si è verificato un crollo di massa a causa della doppia eliminazione: la copia degli oggetti causava comportamenti casuali.
Storia
Nel progetto di un gioco mobile, si è dimenticato di implementare il costruttore di spostamento per la classe contenitore del buffer. Durante lo spostamento, l'oggetto veniva copiato, causando un'eccessiva copia dei dati e cali delle prestazioni.
Storia
Nella libreria di serializzazione delle strutture dati, quando si restituiva un oggetto dalla funzione, veniva restituito un oggetto temporaneo, e il costruttore di copia effettuava una copia superficiale del puntatore. Si sono verificate numerose perdite, manifestatesi solo dopo mesi di lavoro.