ProgrammazioneSviluppatore C++

Descrivi le regole del tre e del cinque (Rule of Three / Rule of Five) in C++11 e la loro importanza nella progettazione delle classi.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

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:

  • Distruttore
  • Costruttore di copia
  • Operatore di assegnazione di copia

C++11: Regola del cinque – sono state aggiunte operazioni di spostamento:

  • Costruttore di spostamento
  • Operatore di assegnazione di spostamento

La violazione di questa regola porta a errori nella gestione delle risorse, come la doppia eliminazione o perdite di memoria.

Esempio di codice:

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; } };

Domanda trabocchetto.

È 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!

Esempi di errori reali a causa della mancanza di conoscenza delle sottigliezze dell'argomento.


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.