Virtual Destructor i C++

Virtual Destructor I C



C++ är språket som används för att ge en förankring i grundkonceptet programmering och gör programmerarnas logiska tänkande starkt. I C++ spelar OOP en viktig roll eftersom OOP är ett objektorienterat språk som skapar objekt i klasser. I OOP studerar vi klasserna och föremålen. Klasser innehåller datamedlemmarna som är variabler av olika typer och olika medlemsfunktioner. Med hjälp av instanser kommer vi åt data från vilken klass som helst. Varje klass har sin konstruktor och destruktor när du skapar klassen. Konstruktorn kallas sig själv när objektet för den klassen skapas. Vi kan också initiera variablerna för en klass inuti konstruktorn. Destruktorer skapas också automatiskt med konstruktorn men destruktorer förstör objektet och det är den sista funktionen som anropas innan objektet förstörs. Namnet på klassen, till exempel klassen 'Profession', skapas. Dess konstruktor är Profession() och destruktorn är ~Profession (). De tre har samma namn.

Efter att ha pratat om OOP, konstruktörer och destruktörer, låt oss nu prata om virtuella förstörare. De virtuella förstörarna, som namnet anger, förstör objektet. Vi har en basklass och en härledd klass som är härledd från basklassen. Båda klasserna har sina konstruktörer och destruktörer. Virtual destructor frigör reminiscens som tilldelas genom det härledda klassobjektet samtidigt som objekten i den härledda klassen raderas med hjälp av en basklasspekare med nyckelordet 'virtuella'.

Varför använder vi Virtual Destructor?

När exekveringen av klassmedlemsfunktionerna är klar eller exekveringen av main()-metoden är på väg att avslutas, anropas destruktorn automatiskt för att frigöra minnet som allokeras under objektskapandet. Varför använder vi en virtuell förstörare? När basklassen raderas som pekar på den härledda klassen, används pekaren (*) här. Basklassförstöraren anropas endast under denna process. Den härledda klassförstöraren anropas inte vilket leder till problem. En av dem är ett problem med minnesläckage. För att undvika detta problem och göra vår kod säker, förstör vi praktiskt taget objekten för att frigöra minnesutrymmet som tilldelades under skapandet av objekt genom att ta bort basklassdestruktorn.

C++ Grundexempel utan Virtual Destructor

Låt oss se hur programmet fungerar utan en virtuell förstörare med ett enkelt program som tar bort pekaren.

Koda:

#include

använder namnutrymme std ;
klass Förälder_Klass0
{
offentlig :
Förälder_Klass0 ( )
{ cout << 'Förälderklasskonstruktör' << endl ; }
~Förälder_Klass0 ( )
{ cout << 'Föräldraklassförstörare' << endl ; }
} ;
klass Barn_1 : offentlig Parent_Class0
{
offentlig :
Barn_1 ( )
{ cout << 'Barnklasskonstruktör' << endl ; }
~Barn_1 ( )
{ cout << 'Child Class Destructor' << endl ; }
} ;
int huvud ( )
{
Förälder_Klass0 * pekare = nytt barn_1 ( ) ;
radera pekaren ;
lämna tillbaka 0 ;
}

Den här koden förklarar hur koden körs utan en virtuell förstörare. Först av allt, skapa en klass som heter 'Parent_Class0' som kommer att vara den överordnade klassen. Inuti den här klassen skapar du en konstruktör och en destruktor. Som vi vet har konstruktören och destruktören samma namn som klassen. Destruktorn representeras på samma sätt som konstruktorn men den har en symbol (~) som skiljer den från konstruktorn. Inuti konstruktorn och destruktorn, skriv ut ett meddelande med 'cout<<'. Skapa nu en annan klass som är 'Child_1'. Den här klassen är härledd från den överordnade klassen, 'Parent_Class0'. Den härledda klassen har sin konstruktor och destruktor som innehåller ett meddelande att skriva ut på utdataskärmen.

I main()-metoden skapar vi en instans av 'Parent_Class0' och tilldelar en härledd klass till den. Den avgörande punkten att komma ihåg i det här fallet är att vi använder en pekare för att hämta den överordnade klassen. När den går in i den överordnade klassen, kör den den överordnade klassens konstruktor. Sedan går den till barnklassen och kör dess konstruktor. Innan den utför destruktören av den underordnade klassen, måste den köra förstöraren av den överordnade klassen. Kompilatorn exekverar förstöraren för den överordnade klassen och avslutar klassen utan att exekvera destruktören för en underordnad klass. Det är problemet; det frigör inte minnet av barnets klass. Det representerar konstruktören av en föräldraklass, konstruktören av en barnklass och förstöraren av en förälderklass. Det visar att förstöraren av en barnklass inte avrättas. Efter denna exekvering tar vi bort pekaren i main()-funktionen.

Produktion:

C++ Exempel med Virtual Destructor

Låt oss diskutera den virtuella förstöraren med en enkel kod för att skilja på hur den fungerar med och utan en virtuell förstörare.

Koda:

#include

använder namnutrymme std ;
klass Förälder_Klass0
{
offentlig :
Förälder_Klass0 ( )
{ cout << 'Förälderklasskonstruktör' << endl ; }
virtuell ~Parent_Class0 ( )
{ cout << 'Föräldraklassförstörare' << endl ; }
} ;
klass Barn_1 : offentlig Parent_Class0
{
offentlig :
Barn_1 ( )
{ cout << 'Barnklasskonstruktör' << endl ; }
virtuell ~Child_1 ( )
{ cout << 'Child Class Destructor' << endl ; }
} ;
int huvud ( )
{
Förälder_Klass0 * pekare = nytt barn_1 ( ) ;
radera pekaren ;
lämna tillbaka 0 ;
}

Det första programmet förklarade problemet som vi står inför utan en virtuell förstörare. Nu kommer den här koden att lösa det problemet med en virtuell förstörare. Kopiera först den första koden och lägg bara till ett nyckelord på två ställen i det här programmet. Det ordet är 'virtuellt'. Infoga detta ord med förstöraren för föräldraklassen, 'Parent_Class0'. På samma sätt nämner du detta med förstöraren för den underordnade klassen som är 'Child_1' som är härledd från den överordnade klassen. Detta 'virtuella' nyckelord gör en liten förändring och det kör förstöraren av barnklassen 'Child_1' först. Sedan kör den förstöraren för föräldraklassen, 'Parent_Class0'. Resten av programmet fungerar på samma sätt som det fungerar utan en virtuell förstörare. Genom att lägga till denna lilla kodbit kan vi rädda vårt minne från läckage. Nu visar den fyra meddelanden på konsolen. Först konstruktören av en föräldraklass, sedan konstruktören av en barnklass, förstöraren av en barnklass och förstöraren av en förälderklass. Till slut tar vi bort pekaren inom main()-metoden.

Produktion:

C++ Exempel på Pure Virtual Destructor

I den här koden kommer vi att prata om den rena virtuella förstöraren, hur den fungerar och hur den skiljer sig från en virtuell förstörare.

Koda:

#include

klass Förälder_0 {
offentlig :
virtuell ~Förälder_0 ( ) = 0 ;
} ;
Förälder_0 :: ~Förälder_0 ( )
{
std :: cout << 'Hej jag är Pure Destructor. Du har ringt mig!' ;
}
klass Barn_0 : offentlig förälder_0 {
offentlig :
~Barn_0 ( ) { std :: cout << 'Den härledda destruktören är här \n ' ; }
} ;

int huvud ( )
{
Förälder_0 * ptr_0 = nytt barn_0 ( ) ;
ta bort ptr_0 ;
lämna tillbaka 0 ;
}

Förälderklassen 'Parent_0' skapas i det första steget i koden. Inuti den, skapa den virtuella överordnade destruktorn och tilldela den med 0. Detta ställer in den virtuella destruktorn till ren virtuell destruktor vilket betyder att den överordnade klassen nu är abstrakt och vi kan inte skapa instanserna av denna klass. Utanför föräldraklassen 'Parent_0', definiera destruktörerna och std::cout. Den önskade texten visas genom att använda std::cout. Härled sedan en 'Child_0'-klass från den överordnade klassen och definiera dess destruktor. Skriv ut ett meddelande inuti förstöraren. I main()-funktionen skapar du pekaren för den överordnade klassen och tilldelar den underordnade klassen.

Kompilatorn går till föräldraklassen 'Parent_0'. När pekaren skapas anropas dess konstruktor automatiskt. Sedan går kompilatorn in i barnklassen för att anropa dess konstruktor. Efter framgångsrik exekvering av konstruktorn kör den förstöraren för en underordnad klass 'Child_0'. Sedan kör den förstöraren av en föräldraklass. På så sätt kan vi göra en ren virtuell förstörare. Det uppmuntras inte att använda det eftersom genom att använda den här metoden blir föräldraklassen abstrakt vilket gör den värdelös. Metoden som oftast används är virtuell destruktor och det är en bra praxis.

Produktion:

Slutsats

Vi lärde oss om den virtuella förstöraren från konceptet OOP till att gå mot konstruktörerna och destruktörerna. Efter att ha förklarat alla dessa diskuterade vi om den virtuella förstöraren i detalj med kodningsexempel och ren virtuell förstörare. Innan vi förklarar den virtuella förstöraren måste vi känna till konstruktörerna, destruktörerna och arvet. I arv ärver vi klasserna från en föräldraklass. Barnklasserna kan vara fler än en men förälderklassen är bara en. Virtuella förstörare och rena virtuella förstörare tillämpas i arv för att rädda från minnesläckaget. Från det grundläggande exemplet till det avancerade exemplet täckte vi allt du borde veta för att komma igång med att använda och praktiskt taget förstöra minnet av den härledda klassen.