Distruttore virtuale in C++

Distruttore Virtuale In C



Il C++ è il linguaggio utilizzato per dare una base al concetto di base della programmazione e rende forte il pensiero logico dei programmatori. In C++, OOP gioca un ruolo fondamentale poiché OOP è un linguaggio orientato agli oggetti che crea gli oggetti delle classi. In OOP, studiamo le classi e gli oggetti. Le classi contengono i membri dati che sono variabili di tipi diversi e funzioni membro diverse. Con l'aiuto delle istanze, accediamo ai dati di qualsiasi classe. Ogni classe ha il suo costruttore e distruttore quando crei la classe. Il costruttore viene chiamato se stesso quando viene creato l'oggetto di quella classe. Possiamo anche inizializzare le variabili di una classe all'interno del costruttore. Anche i distruttori vengono creati automaticamente con il costruttore, ma i distruttori distruggono l'oggetto ed è l'ultima funzione che viene chiamata prima di distruggere l'oggetto. Viene creato il nome della classe, ad esempio la classe “Professione”. Il suo costruttore è Profession() e il distruttore è ~Profession(). I tre hanno lo stesso nome.

Dopo aver parlato dell'OOP, dei costruttori e dei distruttori, parliamo ora dei distruttori virtuali. I distruttori virtuali, come specifica il nome, distruggono l'oggetto. Abbiamo una classe base e una classe derivata derivata dalla classe base. Entrambe le classi hanno i propri costruttori e distruttori. Il distruttore virtuale libera i ricordi assegnati tramite l'oggetto della classe derivata mentre elimina gli oggetti della classe derivata utilizzando un puntatore della classe base con la parola chiave 'virtuale'.

Perché usiamo il distruttore virtuale?

Quando l'esecuzione delle funzioni membro della classe è terminata o l'esecuzione del metodo main() sta per terminare, il distruttore viene chiamato automaticamente per liberare la memoria allocata durante la creazione dell'oggetto. Ora, perché usiamo un distruttore virtuale? Quando viene eliminata la classe base che punta alla classe derivata, qui viene utilizzato il puntatore (*). Il distruttore della classe base viene chiamato solo durante questo processo. Il distruttore di classe derivato non viene chiamato, il che porta a problemi. Uno di questi è un problema di perdita di memoria. Per evitare questo problema e rendere sicuro il nostro codice, distruggiamo virtualmente gli oggetti per liberare lo spazio di memoria assegnato durante la creazione degli oggetti eliminando il distruttore della classe base.

Esempio di base C++ senza distruttore virtuale

Vediamo come funziona il programma senza distruttore virtuale con un semplice programma che cancella il puntatore.

Codice:

#include

utilizzando lo spazio dei nomi std ;
classe Parent_Class0
{
pubblico :
Parent_Class0 ( )
{ cout << 'Costruttore di classe genitore' << finel ; }
~Parent_Class0 ( )
{ cout << 'Distruttore di classe genitore' << finel ; }
} ;
classe Bambino_1 : public Parent_Class0
{
pubblico :
Bambino_1 ( )
{ cout << 'Costruttore di classi figlio' << finel ; }
~Bambino_1 ( )
{ cout << 'Distruttore di classe figlio' << finel ; }
} ;
int principale ( )
{
Parent_Class0 * puntatore = nuovo Bambino_1 ( ) ;
eliminare il puntatore ;
Restituzione 0 ;
}

Questo codice spiega come il codice viene eseguito senza un distruttore virtuale. Prima di tutto, crea una classe chiamata 'Parent_Class0' che sarà la classe genitore. All'interno di questa classe, crea un costruttore e un distruttore. Come sappiamo, il costruttore e il distruttore hanno lo stesso nome della classe. Il distruttore è rappresentato in modo simile al costruttore ma ha un simbolo (~) che lo differenzia dal costruttore. All'interno del costruttore e del distruttore, stampa un messaggio usando 'cout<<'. Ora crea un'altra classe che è 'Child_1'. Questa classe è derivata dalla classe genitore, “Parent_Class0”. La classe derivata ha il suo costruttore e distruttore che contengono un messaggio da stampare sullo schermo di output.

Nel metodo main(), creiamo un'istanza di 'Parent_Class0' e le assegniamo una classe derivata. Il punto cruciale da ricordare in questo caso è che utilizziamo un puntatore per recuperare la classe genitore. Quando entra nella classe genitore, esegue il costruttore della classe genitore. Quindi, va alla classe figlia ed esegue il suo costruttore. Prima di eseguire il distruttore della classe figlia, deve eseguire il distruttore della classe genitore. Il compilatore esegue il distruttore della classe genitore e termina la classe senza eseguire il distruttore di una classe figlia. Quello è il problema; non libera il ricordo della classe del bambino. Rappresenta il costruttore di una classe genitore, il costruttore di una classe figlia e il distruttore di una classe genitore. Ciò dimostra che il distruttore di una classe figlia non viene eseguito. Dopo questa esecuzione, eliminiamo il puntatore nella funzione main().

Produzione:

Esempio C++ con distruttore virtuale

Parliamo del distruttore virtuale con un semplice codice per differenziare il modo in cui funziona con e senza un distruttore virtuale.

Codice:

#include

utilizzando lo spazio dei nomi std ;
classe Parent_Class0
{
pubblico :
Parent_Class0 ( )
{ cout << 'Costruttore di classe genitore' << finel ; }
virtuale ~Parent_Class0 ( )
{ cout << 'Distruttore di classe genitore' << finel ; }
} ;
classe Bambino_1 : public Parent_Class0
{
pubblico :
Bambino_1 ( )
{ cout << 'Costruttore di classi figlio' << finel ; }
virtuale ~Bambino_1 ( )
{ cout << 'Distruttore di classe figlio' << finel ; }
} ;
int principale ( )
{
Parent_Class0 * puntatore = nuovo Bambino_1 ( ) ;
eliminare il puntatore ;
Restituzione 0 ;
}

Il primo programma ha spiegato il problema che stiamo affrontando senza un distruttore virtuale. Ora, questo codice risolverà il problema utilizzando un distruttore virtuale. Innanzitutto, copia il primo codice e aggiungi solo una parola chiave in due punti in questo programma. Quella parola è 'virtuale'. Inserisci questa parola con il distruttore della classe genitore, “Parent_Class0”. Allo stesso modo, menzionalo con il distruttore della classe figlia che è 'Child_1' derivato dalla classe genitore. Questa parola chiave 'virtuale' apporta una piccola modifica ed esegue prima il distruttore della classe figlia 'Child_1'. Quindi, esegue il distruttore della classe genitore, 'Parent_Class0'. Il resto del programma funziona allo stesso modo in cui funziona senza un distruttore virtuale. Aggiungendo questo piccolo pezzo di codice, possiamo salvare la nostra memoria dalle perdite. Ora visualizza quattro messaggi sulla console. Innanzitutto, il costruttore di una classe genitore, quindi il costruttore di una classe figlia, il distruttore di una classe figlia e il distruttore di una classe genitore. Alla fine, eliminiamo il puntatore all'interno del metodo main().

Produzione:

Esempio C++ di distruttore virtuale puro

In questo codice parleremo del distruttore virtuale puro, di come funziona e di come è diverso da un distruttore virtuale.

Codice:

#include

classe Genitore_0 {
pubblico :
virtuale ~Genitore_0 ( ) = 0 ;
} ;
Genitore_0 :: ~Genitore_0 ( )
{
standard :: cout << 'Ciao, sono Pure Destructor. Mi hai chiamato!' ;
}
classe Bambino_0 : public Parent_0 {
pubblico :
~Bambino_0 ( ) { standard :: cout << 'Il distruttore derivato è qui \n ' ; }
} ;

int principale ( )
{
Genitore_0 * ptr_0 = nuovo Bambino_0 ( ) ;
eliminare ptr_0 ;
Restituzione 0 ;
}

La classe genitore 'Parent_0' viene creata nel primo passaggio del codice. Al suo interno, crea il distruttore genitore virtuale e assegnalo con 0. Questo imposta il distruttore virtuale su puro distruttore virtuale, il che significa che la classe genitore è ora astratta e non possiamo creare le istanze di questa classe. Al di fuori della classe genitore 'Parent_0', definire i distruttori e std::cout. Il testo richiesto viene visualizzato utilizzando std::cout. Quindi, deriva una classe 'Child_0' dalla classe genitore e definisci il suo distruttore. All'interno del distruttore, stampa un messaggio. Nella funzione main(), crea il puntatore della classe genitore e assegnagli la classe figlia.

Il compilatore passa alla classe genitore 'Parent_0'. Quando viene creato il puntatore, viene chiamato automaticamente il suo costruttore. Quindi, il compilatore entra nella classe figlia per richiamare il suo costruttore. Dopo l'esecuzione riuscita del costruttore, esegue il distruttore di una classe figlia “Child_0”. Quindi, esegue il distruttore di una classe genitore. In questo modo, possiamo creare un puro distruttore virtuale. Non è incoraggiato utilizzarlo perché utilizzando questo metodo, la classe genitore diventa astratta, il che la rende inutile. La metodologia maggiormente utilizzata è il distruttore virtuale ed è una buona pratica.

Produzione:

Conclusione

Abbiamo imparato a conoscere il distruttore virtuale partendo dal concetto di OOP per spostarci verso costruttori e distruttori. Dopo aver spiegato tutto ciò, abbiamo discusso in dettaglio del distruttore virtuale con esempi di codifica e distruttore virtuale puro. Prima di spiegare il distruttore virtuale, dobbiamo conoscere i costruttori, i distruttori e l'ereditarietà. In ereditarietà, ereditiamo le classi da una classe genitore. Le classi figlie possono essere più di una ma la classe genitore è solo una. I distruttori virtuali e i distruttori virtuali puri vengono applicati in eredità per evitare perdite di memoria. Dall'esempio di base all'esempio avanzato, abbiamo coperto tutto ciò che dovresti sapere per iniziare a usare e distruggere virtualmente la memoria della classe derivata.