ProgrammazioneSviluppatore C++

Che cos'è un distruttore virtuale in C++ e a cosa serve? Fai un esempio di comportamento errato in assenza di un distruttore virtuale.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Un distruttore virtuale è un distruttore dichiarato con la parola chiave virtual nella classe base. Questo garantisce che venga chiamato il distruttore della classe derivata quando si elimina un oggetto tramite un puntatore alla classe base.

class Base { public: virtual ~Base() { /* ... */ } }; class Derived : public Base { public: ~Derived() override { /* ... */ } }; Base* ptr = new Derived(); delete ptr; // Verranno chiamati entrambi i distruttori

Senza un distruttore virtuale, il comportamento potrebbe essere errato: il distruttore della classe derivata non sarà chiamato, il che porterà a una perdita di risorse!


Domanda insidiosa.

È necessario dichiarare un distruttore come virtuale se nella tua classe base non ci sono funzioni virtuali?

Risposta: Sì, se si prevede di ereditare dalla classe e di eliminare tramite puntatore al tipo base. Anche se non ci sono altre funzioni virtuali, la virtualità del distruttore è necessaria per una corretta eliminazione dei discendenti.

class Shape { public: virtual ~Shape() {} };

Esempi di errori reali a causa della mancanza di conoscenze sulle sottigliezze dell'argomento.


Storia 1

In un grande progetto di una libreria grafica, durante l'eliminazione di oggetti di disegno tramite un puntatore alla classe base, si verificavano perdite di risorse OpenGL (buffer, texture) - le relative liberazioni si trovavano nei distruttori delle classi derivate, e questi non venivano chiamati.


Storia 2

In una libreria di rete per il protocollo TCP, durante l'eliminazione delle sessioni, non veniva chiamato il distruttore dei discendenti, gestiti tramite un'interfaccia base comune. Questo ha portato a un massiccio blocco dei socket e all'esaurimento dei limiti dei descrittori.


Storia 3

In un sistema embedded in C++, un distruttore della classe base dichiarato in modo errato (non virtuale) ha provocato una perdita di memoria per le risorse di sistema dei controller di input/output, causando il malfunzionamento dei dispositivi dopo alcuni cicli di aggiornamento dei driver.