Efter at have talt om OOP, konstruktører og destruktorer, lad os nu tale om virtuelle destruktorer. De virtuelle destruktorer, som navnet angiver, ødelægger objektet. Vi har en basisklasse og en afledt klasse, der er afledt af basisklassen. Begge klasser har deres konstruktører og destruktorer. Virtuel destructor frigør reminiscens, som tildeles gennem det afledte klasseobjekt, mens objekterne i den afledte klasse slettes ved hjælp af en basisklassepointer med det 'virtuelle' nøgleord.
Hvorfor bruger vi Virtual Destructor?
Når udførelsen af klassemedlemsfunktionerne er færdig, eller udførelsen af main()-metoden er ved at afslutte, kaldes destruktoren automatisk for at frigøre den hukommelse, der er allokeret under objektoprettelsen. Nu, hvorfor bruger vi en virtuel destruktor? Når basisklassen slettes, der peger på den afledte klasse, bruges markøren (*) her. Basisklassedestruktoren kaldes kun under denne proces. Den afledte klassedestruktor kaldes ikke, hvilket fører til problemer. En af dem er et problem med hukommelseslækage. For at undgå dette problem og gøre vores kode sikker, ødelægger vi praktisk talt objekterne for at frigøre den hukommelsesplads, der blev tildelt under oprettelsen af objekter, ved at slette basisklassedestruktoren.
C++ Grundlæggende eksempel uden Virtual Destructor
Lad os se, hvordan programmet fungerer uden en virtuel destruktor med et simpelt program, der sletter markøren.
Kode:
#includebruger navneområde std ;
klasse Forælder_Klasse0
{
offentlig :
Forældre_Klasse0 ( )
{ cout << 'Forældreklassekonstruktør' << endl ; }
~Forældreklasse0 ( )
{ cout << 'Forældreklassedestruktor' << endl ; }
} ;
klasse Barn_1 : offentlig forældreklasse0
{
offentlig :
Barn_1 ( )
{ cout << 'Børneklasseskonstruktør' << endl ; }
~Barn_1 ( )
{ cout << 'Child Class Destructor' << endl ; }
} ;
int vigtigste ( )
{
Forældre_Klasse0 * pointer = nyt barn_1 ( ) ;
slet markøren ;
Vend tilbage 0 ;
}
Denne kode forklarer, hvordan koden udføres uden en virtuel destruktor. Først og fremmest skal du oprette en klasse ved navn 'Parent_Class0', som vil være den overordnede klasse. Inde i denne klasse skal du oprette en konstruktør og destruktor. Som vi ved, hedder konstruktøren og destruktoren det samme som klassen. Destruktoren er repræsenteret på samme måde som konstruktøren, men den har et symbol (~), der adskiller den fra konstruktøren. Inde i konstruktøren og destruktoren skal du udskrive en besked ved hjælp af 'cout<<'. Opret nu en anden klasse, som er 'Child_1'. Denne klasse er afledt af den overordnede klasse, 'Parent_Class0'. Den afledte klasse har sin konstruktør og destruktor, der indeholder en besked, der skal udskrives på outputskærmen.
I main()-metoden opretter vi en instans af 'Parent_Class0' og tildeler en afledt klasse til den. Det afgørende punkt at huske i dette tilfælde er, at vi bruger en pointer til at hente den overordnede klasse. Når den går ind i den overordnede klasse, udfører den den overordnede klasse-konstruktør. Derefter går den til børneklassen og udfører sin konstruktør. Før den udfører destructoren af den underordnede klasse, skal den udføre destructoren af den overordnede klasse. Compileren udfører destruktoren af den overordnede klasse og afslutter klassen uden at udføre destructoren af en underordnet klasse. Det er problemet; det frigør ikke hukommelsen om barnets klasse. Det repræsenterer konstruktøren af en overordnet klasse, konstruktøren af en underordnet klasse og destruktoren af en overordnet klasse. Det viser, at ødelæggeren af en børneklasse ikke bliver henrettet. Efter denne udførelse sletter vi markøren i main()-funktionen.
Produktion:
C++ Eksempel med Virtual Destructor
Lad os diskutere den virtuelle destruktor med en simpel kode for at skelne mellem, hvordan den fungerer med og uden en virtuel destruktor.
Kode:
#includebruger navneområde std ;
klasse Forælder_Klasse0
{
offentlig :
Forældre_Klasse0 ( )
{ cout << 'Forældreklassekonstruktør' << endl ; }
virtuel ~Forældreklasse0 ( )
{ cout << 'Forældreklassedestruktor' << endl ; }
} ;
klasse Barn_1 : offentlig forældreklasse0
{
offentlig :
Barn_1 ( )
{ cout << 'Børneklasseskonstruktør' << endl ; }
virtuel ~Child_1 ( )
{ cout << 'Child Class Destructor' << endl ; }
} ;
int vigtigste ( )
{
Forældre_Klasse0 * pointer = nyt barn_1 ( ) ;
slet markøren ;
Vend tilbage 0 ;
}
Det første program forklarede det problem, vi står over for uden en virtuel destruktor. Nu vil denne kode løse det problem ved hjælp af en virtuel destruktor. Først skal du kopiere den første kode og blot tilføje et nøgleord to steder i dette program. Det ord er 'virtuelt'. Indsæt dette ord med destruktoren for forældreklassen, 'Parent_Class0'. På samme måde nævner du dette med destruktoren for den underordnede klasse, som er 'Child_1', der er afledt af den overordnede klasse. Dette 'virtuelle' søgeord gør en lille ændring, og det udfører destruktoren af 'Child_1'-underklassen først. Derefter udfører den destruktoren for forældreklassen, 'Parent_Class0'. Resten af programmet fungerer på samme måde, som det fungerer uden en virtuel destruktor. Ved at tilføje dette lille stykke kode kan vi redde vores hukommelse fra lækage. Nu viser den fire meddelelser på konsollen. Først konstruktøren af en overordnet klasse, derefter konstruktøren af en børneklasse, destruktoren af en børneklasse og destruktoren af en overordnet klasse. Til sidst sletter vi markøren i main()-metoden.
Produktion:
C++ Eksempel på Pure Virtual Destructor
I denne kode vil vi tale om den rene virtuelle destruktor, hvordan den virker, og hvordan den adskiller sig fra en virtuel destructor.
Kode:
#includeklasse Forælder_0 {
offentlig :
virtuel ~Forælder_0 ( ) = 0 ;
} ;
Forælder_0 :: ~Forælder_0 ( )
{
std :: cout << 'Hej jeg er Pure Destructor. Du har kaldt mig!' ;
}
klasse Barn_0 : offentlig Forælder_0 {
offentlig :
~Barn_0 ( ) { std :: cout << 'Afledt destruktor er her \n ' ; }
} ;
int vigtigste ( )
{
Forælder_0 * ptr_0 = nyt barn_0 ( ) ;
slet ptr_0 ;
Vend tilbage 0 ;
}
Forælderklassen 'Parent_0' oprettes i det første trin af koden. Inde i den skal du oprette den virtuelle overordnede destruktor og tildele den 0. Dette sætter den virtuelle destruktor til ren virtuel destruktor, hvilket betyder, at den overordnede klasse nu er abstrakt, og vi kan ikke oprette forekomsterne af denne klasse. Uden for forældreklassen 'Parent_0', definer destruktorerne og std::cout. Den påkrævede tekst vises ved at bruge std::cout. Udled derefter en 'Child_0'-klasse fra den overordnede klasse og definer dens destruktor. Udskriv en besked inde i destruktoren. I main()-funktionen skal du oprette markøren for den overordnede klasse og tildele den underordnede klasse til den.
Compileren går til forældreklassen 'Parent_0'. Når markøren er oprettet, kaldes dens konstruktør automatisk. Derefter går compileren ind i børneklassen for at påkalde dens konstruktør. Efter den vellykkede udførelse af konstruktøren, udfører den destruktoren af en underordnet klasse 'Child_0'. Derefter udfører den destruktoren af en overordnet klasse. På denne måde kan vi lave en ren virtuel destruktor. Det opfordres ikke til at bruge det, fordi ved at anvende denne metode bliver forældreklassen abstrakt, hvilket gør den ubrugelig. Metoden, der oftest bruges, er virtuel destruktor, og det er en god praksis.
Produktion:
Konklusion
Vi lærte om den virtuelle destruktor fra konceptet OOP til at bevæge os mod konstruktørerne og destruktorerne. Efter at have forklaret alle disse, diskuterede vi om den virtuelle destructor i detaljer med kodningseksempler og ren virtuel destructor. Før vi forklarer den virtuelle destruktor, skal vi kende til konstruktørerne, destructorerne og arven. I arv arver vi klasserne fra en forældreklasse. Børneklasserne kan være mere end én, men forældreklassen er kun én. Virtuelle destruktorer og rene virtuelle destruktorer anvendes i arv for at redde fra hukommelseslækagen. Fra det grundlæggende eksempel til det avancerede eksempel dækkede vi alt, hvad du burde vide for at komme i gang med at bruge og nærmest ødelægge hukommelsen om den afledte klasse.