Virtuele destructor in C++

Virtuele Destructor In C



C++ is de taal die wordt gebruikt om een ​​basis te leggen in het basisconcept van programmeren en maakt het logisch denken van de programmeurs sterk. In C++ speelt OOP een cruciale rol, aangezien OOP een objectgeoriënteerde taal is die de objecten van klassen maakt. In OOP bestuderen we de klassen en objecten. Klassen bevatten de gegevensleden die variabelen van verschillende typen en verschillende lidfuncties zijn. Met behulp van instanties hebben we toegang tot de gegevens van elke klasse. Elke klasse heeft zijn constructor en destructor wanneer u de klasse maakt. De constructor wordt zichzelf genoemd wanneer het object van die klasse wordt gemaakt. We kunnen ook de variabelen van een klasse binnen de constructor initialiseren. Destructors worden ook automatisch gemaakt met de constructor, maar destructors vernietigen het object en het is de laatste functie die wordt aangeroepen voordat het object wordt vernietigd. De naam van de klasse, bijvoorbeeld de klasse 'Profession', wordt aangemaakt. De constructor is Profession() en de destructor is ~Profession (). Ze hebben alle drie dezelfde naam.

Nadat we het hebben gehad over de OOP, constructors en destructors, gaan we het nu hebben over virtuele destructors. De virtuele destructors, zoals de naam aangeeft, vernietigen het object. We hebben een basisklasse en een afgeleide klasse die is afgeleid van de basisklasse. Beide klassen hebben hun constructors en destructors. Virtuele destructor maakt herinneringen vrij die zijn toegewezen via het afgeleide klassenobject, terwijl de objecten van de afgeleide klasse worden verwijderd met behulp van een basisklasse-aanwijzer met het 'virtuele' trefwoord.

Waarom gebruiken we de virtuele vernietiger?

Wanneer de uitvoering van de klasselidfuncties is voltooid of de uitvoering van de methode main() bijna is afgelopen, wordt de destructor automatisch aangeroepen om het geheugen vrij te maken dat is toegewezen tijdens het maken van het object. Waarom gebruiken we een virtuele destructor? Wanneer de basisklasse wordt verwijderd die verwijst naar de afgeleide klasse, wordt hier de aanwijzer (*) gebruikt. De destructor van de basisklasse wordt alleen tijdens dit proces aangeroepen. De afgeleide klassenvernietiger wordt niet aangeroepen, wat tot problemen leidt. Een daarvan is een probleem met geheugenlekkage. Om dit probleem te voorkomen en onze code te beveiligen, vernietigen we de objecten virtueel om de geheugenruimte vrij te maken die was toegewezen tijdens het maken van objecten door de destructor van de basisklasse te verwijderen.

C++ Basisvoorbeeld zonder Virtual Destructor

Laten we eens kijken hoe het programma werkt zonder een virtuele destructor met een eenvoudig programma dat de aanwijzer verwijdert.

Code:

#include

namespace std; gebruiken ;
klasse Parent_Class0
{
openbaar :
Parent_Class0 ( )
{ cout << 'Ouderklas Constructor' << eindel ; }
~Parent_Class0 ( )
{ cout << 'Ouderklas Destructor' << eindel ; }
} ;
klasse Kind_1 : openbare Parent_Class0
{
openbaar :
Kind_1 ( )
{ cout << 'Kinderklas Constructeur' << eindel ; }
~Kind_1 ( )
{ cout << 'Kinderklasse vernietiger' << eindel ; }
} ;
int voornaamst ( )
{
Parent_Class0 * wijzer = nieuw Kind_1 ( ) ;
aanwijzer verwijderen ;
opbrengst 0 ;
}

Deze code legt uit hoe de code wordt uitgevoerd zonder een virtuele destructor. Maak allereerst een klasse met de naam 'Parent_Class0' die de bovenliggende klasse zal zijn. Maak binnen deze klasse een constructor en destructor. Zoals we weten, hebben de constructor en de destructor dezelfde naam als de klasse. De destructor wordt op dezelfde manier weergegeven als de constructor, maar heeft een symbool (~) dat hem onderscheidt van de constructor. Druk binnen de constructor en destructor een bericht af met 'cout<<'. Maak nu een andere klas aan die 'Child_1' is. Deze klasse is afgeleid van de bovenliggende klasse, 'Parent_Class0'. De afgeleide klasse heeft zijn constructor en destructor die een bericht bevatten om af te drukken op het uitvoerscherm.

In de methode main() maken we een instantie van de 'Parent_Class0' en wijzen we er een afgeleide klasse aan toe. Het cruciale punt om in dit geval te onthouden, is dat we een aanwijzer gebruiken om de bovenliggende klasse op te halen. Wanneer het binnen de bovenliggende klasse gaat, voert het de constructor van de bovenliggende klasse uit. Vervolgens gaat het naar de kindklasse en voert het de constructor uit. Voordat de destructor van de onderliggende klasse wordt uitgevoerd, moet deze de destructor van de bovenliggende klasse uitvoeren. De compiler voert de destructor van de bovenliggende klasse uit en beëindigt de klasse zonder de destructor van een onderliggende klasse uit te voeren. Dat is het probleem; het maakt de herinnering aan de klas van het kind niet vrij. Het vertegenwoordigt de constructor van een bovenliggende klasse, de constructor van een onderliggende klasse en de destructor van een bovenliggende klasse. Dat laat zien dat de destructor van een onderliggende klasse niet wordt uitgevoerd. Na deze uitvoering verwijderen we de pointer in de main() functie.

Uitgang:

C++ Voorbeeld met Virtual Destructor

Laten we de virtuele destructor bespreken met een eenvoudige code om te onderscheiden hoe het werkt met en zonder een virtuele destructor.

Code:

#include

namespace std; gebruiken ;
klasse Parent_Class0
{
openbaar :
Parent_Class0 ( )
{ cout << 'Ouderklas Constructor' << eindel ; }
virtueel ~Parent_Class0 ( )
{ cout << 'Ouderklas Destructor' << eindel ; }
} ;
klasse Kind_1 : openbare Parent_Class0
{
openbaar :
Kind_1 ( )
{ cout << 'Kinderklas Constructor' << eindel ; }
virtueel ~Kind_1 ( )
{ cout << 'Kinderklasse vernietiger' << eindel ; }
} ;
int voornaamst ( )
{
Parent_Class0 * wijzer = nieuw Kind_1 ( ) ;
aanwijzer verwijderen ;
opbrengst 0 ;
}

Het eerste programma legde het probleem uit waarmee we worden geconfronteerd zonder een virtuele destructor. Nu lost deze code dat probleem op met behulp van een virtuele destructor. Kopieer eerst de eerste code en voeg gewoon één trefwoord op twee plaatsen in dit programma toe. Dat woord is 'virtueel'. Voeg dit woord in met de destructor van de bovenliggende klasse, 'Parent_Class0'. Vermeld dit op dezelfde manier met de destructor van de onderliggende klasse die 'Child_1' is en is afgeleid van de bovenliggende klasse. Dit 'virtuele' trefwoord brengt een kleine verandering aan en voert eerst de destructor van de 'Child_1' kindklasse uit. Vervolgens voert het de destructor van de bovenliggende klasse 'Parent_Class0' uit. De rest van het programma werkt hetzelfde als zonder een virtuele destructor. Door dit kleine stukje code toe te voegen, kunnen we voorkomen dat ons geheugen lekt. Nu worden er vier berichten op de console weergegeven. Eerst de constructor van een bovenliggende klasse, vervolgens de constructor van een onderliggende klasse, de destructor van een onderliggende klasse en de destructor van een bovenliggende klasse. Uiteindelijk verwijderen we de aanwijzer binnen de main() methode.

Uitgang:

C++ Voorbeeld van Pure Virtual Destructor

In deze code zullen we het hebben over de pure virtuele destructor, hoe deze werkt en hoe deze verschilt van een virtuele destructor.

Code:

#include

klasse Parent_0 {
openbaar :
virtueel ~Parent_0 ( ) = 0 ;
} ;
Ouder_0 :: ~Parent_0 ( )
{
soa :: cout << 'Hallo, ik ben Pure Destructor. Je hebt me gebeld!' ;
}
klasse Kind_0 : openbare ouder_0 {
openbaar :
~Kind_0 ( ) { soa :: cout << 'Afgeleide destructor is hier \n ' ; }
} ;

int voornaamst ( )
{
Ouder_0 * ptr_0 = nieuwe Kind_0 ( ) ;
verwijder ptr_0 ;
opbrengst 0 ;
}

De bovenliggende klasse 'Parent_0' wordt gemaakt in de eerste stap van de code. Maak binnenin de virtuele bovenliggende destructor en wijs deze toe met 0. Dit stelt de virtuele destructor in op pure virtuele destructor, wat betekent dat de bovenliggende klasse nu abstract is en dat we de instanties van deze klasse niet kunnen maken. Definieer buiten de bovenliggende klasse 'Parent_0' de destructors en std::cout. De vereiste tekst wordt getoond door gebruik te maken van de std::cout. Leid vervolgens een klasse 'Child_0' af van de bovenliggende klasse en definieer de destructor. Druk een bericht af in de destructor. Maak in de functie main() de aanwijzer van de bovenliggende klasse en wijs er de onderliggende klasse aan toe.

De compiler gaat naar de bovenliggende klasse 'Parent_0'. Wanneer de aanwijzer is gemaakt, wordt de constructor automatisch aangeroepen. Vervolgens gaat de compiler naar de kindklasse om de constructor aan te roepen. Na de succesvolle uitvoering van de constructor, wordt de destructor van een onderliggende klasse 'Child_0' uitgevoerd. Vervolgens voert het de destructor van een bovenliggende klasse uit. Op deze manier kunnen we een pure virtuele destructor maken. Het wordt niet aangemoedigd om het te gebruiken omdat door deze methode te gebruiken, de bovenliggende klasse abstract wordt, waardoor het onbruikbaar wordt. De meest gebruikte methode is virtuele destructor en het is een goede gewoonte.

Uitgang:

Conclusie

We leerden over de virtuele destructor vanaf het concept van OOP tot aan de constructors en de destructors. Nadat we dit allemaal hadden uitgelegd, bespraken we de virtuele destructor in detail met coderingsvoorbeelden en pure virtuele destructor. Voordat we de virtuele destructor uitleggen, moeten we de constructors, destructors en overerving kennen. Bij overerving erven we de klassen van een bovenliggende klasse. De onderliggende klassen kunnen meer dan één zijn, maar de bovenliggende klasse is er slechts één. Virtuele destructors en pure virtuele destructors worden in overerving toegepast om geheugenlekkage te voorkomen. Van het basisvoorbeeld tot het geavanceerde voorbeeld, we hebben alles besproken wat u moet weten om aan de slag te gaan met het gebruik en het virtueel vernietigen van het geheugen van de afgeleide klasse.