Wirtualny destruktor w C ++

Wirtualny destruktor w C ++
C ++ jest językiem, który służy do zapewnienia podstawowej koncepcji programowania i sprawia, że ​​logiczne myślenie programistów jest silne. W C ++ OOP odgrywa istotną rolę, ponieważ OOP jest językiem zorientowanym na obiekt, który tworzy obiekty klas. W OOP badamy klasy i obiekty. Klasy zawierają elementy danych, które są zmiennymi różnych typów i różnych funkcji członków. Za pomocą instancji uzyskujemy dostęp do danych dowolnej klasy. Każda klasa ma swój konstruktor i destruktor, gdy tworzysz klasę. Konstruktor jest nazywany samym obiektem tej klasy. Możemy również zainicjować zmienne klasy wewnątrz konstruktora. Destruki są również automatycznie tworzone za pomocą konstruktora, ale destruktory niszczą obiekt i jest to ostatnia funkcja wywoływana przed zniszczeniem obiektu. Nazwa klasy, na przykład klasa „zawodu”, jest tworzona. Jego konstruktor jest zawód (), a destruktor jest ~ profesjonalistą (). Trzy z nich mają to samo imię.

Po rozmowie o Oop, konstruktorach i destruktorach, porozmawiajmy teraz o wirtualnych destrukturach. Wirtualne destruktury, jak określają nazwa, niszczą obiekt. Mamy klasę podstawową i klasę pochodną, ​​która pochodzi z klasy podstawowej. Obie klasy mają swoje konstruktory i niszczyciele. Wirtualny destruktor uwalnia wspomnienie, które są przydzielane przez obiekt klasy pochodnej, jednocześnie usuwając obiekty klasy pochodnej za pomocą wskaźnika klasy podstawowej z słowem kluczowym „wirtualnym”.

Dlaczego używamy wirtualnego destruktura?

Gdy wykonanie funkcji członka klasy lub wykonywanie metody main (. Dlaczego używamy wirtualnego destruktura? Gdy klasa podstawowa zostanie usunięta, która wskazuje na klasę pochodną, ​​wskaźnik (*) jest tutaj używany. Destrukt klasy podstawowej jest wywoływany tylko podczas tego procesu. Destruktor klas pochodnych nie jest wywoływany, co prowadzi do problemów. Jednym z nich jest problem z wyciekiem pamięci. Aby uniknąć tego problemu i zapewnić nasz kod bezpieczny, praktycznie niszczymy obiekty, aby zwolnić przestrzeń pamięci przydzieloną podczas tworzenia obiektów, usuwając destruktor klasy podstawowej.

C ++ Podstawowy przykład bez wirtualnego destruktura

Zobaczmy, jak program funkcjonuje bez wirtualnego destruktura z prostym programem, który usuwa wskaźnik.

Kod:

#włączać
za pomocą przestrzeni nazw Std;
klasa macierz_class0

publiczny:
Marent_class0 ()
cout<< "Parent Class Constructor" <~ Parent_class0 ()
cout<< "Parent Class Destructor" <;
Klasa Child_1: Public Parent_class0

publiczny:
Child_1 ()
cout<< "Child Class Constructor" <~ Child_1 ()
cout<< "Child Class Destructor" <;
int main ()

Pary_class0*wskaźnik = new child_1 ();
Usuń wskaźnik;
powrót 0;

Ten kod wyjaśnia, w jaki sposób kod wykonuje się bez wirtualnego destrutora. Przede wszystkim utwórz klasę o nazwie „Parent_class0”, która będzie klasą nadrzędną. W tej klasie stwórz konstruktor i destruktor. Jak wiemy, konstruktor i niszczyciel są nazywane tak samo jak klasa. Destruktor jest reprezentowany podobnie do konstruktora, ale ma symbol (~), który odróżnia go od konstruktora. Wewnątrz konstruktora i destruktura wydrukuj wiadomość za pomocą „Cout<<”. Now, create another class which is “Child_1”. This class is derived from the parent class, “Parent_Class0”. The derived class has its constructor and destructor that contain a message to print on the output screen.

W metodzie main () tworzymy instancję „pary_class0” i przypisujemy do niej klasę pochodną. Kluczową kwestią do zapamiętania w tym przypadku jest to, że wykorzystujemy wskaźnik do odzyskania klasy nadrzędnej. Kiedy wejdzie do klasy nadrzędnej, wykonuje konstruktor klasy nadrzędnej. Następnie trafia do klasy dzieci i wykonuje swój konstruktor. Przed wykonaniem destrukta klasy dziecka musi wykonać destruktor klasy nadrzędnej. Kompilator wykonuje niszczyciel klasy nadrzędnej i kończy klasę bez wykonywania destrukta klasy dziecka. To jest problem; nie uwolni pamięci klasy dziecka. Reprezentuje konstruktor klasy nadrzędnej, konstruktor klasy dziecięcej i destruktor klasy macierzystej. To pokazuje, że niszczyciel klasy dzieci nie jest wykonywany. Po tym wykonaniu usuwamy wskaźnik w funkcji Main ().

Wyjście:

Przykład C ++ z wirtualnym destruktorem

Omówmy wirtualnego destruktora z prostym kodem, aby rozróżnić, jak działa z wirtualnym destruktorem i bez.

Kod:

#włączać
za pomocą przestrzeni nazw Std;
klasa macierz_class0

publiczny:
Marent_class0 ()
cout<< "Parent Class Constructor" <Virtual ~ Parent_class0 ()
cout<< "Parent Class Destructor" <;
Klasa Child_1: Public Parent_class0

publiczny:
Child_1 ()
cout<< "Child Class Constructor" <Virtual ~ Child_1 ()
cout<< "Child Class Destructor" <;
int main ()

Pary_class0*wskaźnik = new child_1 ();
Usuń wskaźnik;
powrót 0;

Pierwszy program wyjaśnił problem, przed którym stoimy bez wirtualnego destruktura. Teraz ten kod rozwiąże ten problem za pomocą wirtualnego destruktura. Najpierw skopiuj pierwszy kod i po prostu dodaj jedno słowo kluczowe w dwóch miejscach w tym programie. To słowo jest „wirtualne”. Włóż to słowo z destruktorem klasy nadrzędnej „Parent_class0”. Podobnie wspomnij o tym z destruktorem klasy dziecięcej, która jest „child_1”, która pochodzi z klasy nadrzędnej. To „wirtualne” słowo kluczowe wprowadza trochę zmian i najpierw wykonuje destruktor klasy dzieci „Child_1”. Następnie wykonuje destruktor klasy nadrzędnej „Parent_class0”. Reszta programu działa tak samo, jak działa bez wirtualnego destruktura. Dodając ten mały kawałek kodu, możemy zapisać naszą pamięć przed wyciekiem. Teraz wyświetla cztery wiadomości na konsoli. Najpierw konstruktor klasy macierzystej, a następnie konstruktor klasy dziecięcej, destruktor klasy dziecka i zniszczak klasy rodzicielskiej. Ostatecznie usuwamy wskaźnik w metodzie Main ().

Wyjście:

C ++ Przykład czystego wirtualnego destruktura

W tym kodzie porozmawiamy o czystym wirtualnym destruktorze, o tym, jak to działa i jak różni się od wirtualnego destruktura.

Kod:

#włączać
klasa rodzica_0
publiczny:
Virtual ~ Parent_0 () = 0;
;
Pary_0 :: ~ marent_0 ()

STD :: Cout<< "Hello I am Pure Destructor. You Called Me!";

Klasa Child_0: public Parent_0
publiczny:
~ Child_0 () std :: cout<< "Derived destructor is here\n";
;
int main ()

Pary_0* ptr_0 = new child_0 ();
usuń ptr_0;
powrót 0;

Klasa nadrzędna „Parent_0” jest tworzona w pierwszym etapie kodu. W środku utwórz wirtualny destruktor nadrzędny i przypisz go z 0. To ustawia wirtualny destruktor na czystego wirtualnego destruktura, co oznacza, że ​​klasa nadrzędna jest teraz abstrakcyjna i nie możemy stworzyć instancji tej klasy. Poza klasą nadrzędną „Parent_0”, zdefiniuj destruktury i std :: cout. Wymagany tekst jest wyświetlany przy użyciu STD :: Cout. Następnie wyprowadzić klasę „Child_0” z klasy nadrzędnej i zdefiniuj jej destruktor. Wewnątrz destruktora wydrukuj wiadomość. W funkcji main () utwórz wskaźnik klasy nadrzędnej i przypisz do niej klasę dziecięcą.

Kompilator przechodzi do klasy nadrzędnej „Parent_0”. Po utworzeniu wskaźnika jego konstruktor jest automatycznie wywoływany. Następnie kompilator wchodzi do klasy dzieci, aby wywołać jego konstruktor. Po pomyślnym wykonaniu konstruktora wykonuje destruktor klasy dziecięcej „Child_0”. Następnie wykonuje destruktor klasy nadrzędnej. W ten sposób możemy zrobić czystego wirtualnego destruktura. Nie zachęca się go do korzystania z niego, ponieważ stosując tę ​​metodę, klasa nadrzędna staje się abstrakcyjna, co czyni ją bezużyteczną. Metodologia, która jest najczęściej używana, jest wirtualna i jest to dobra praktyka.

Wyjście:

Wniosek

Dowiedzieliśmy się o wirtualnym destruktorze od koncepcji OOP do przejścia w kierunku konstruktorów i destruktorów. Po wyjaśnieniu wszystkich, szczegółowo omówiliśmy wirtualny destruktor z przykładami kodowania i czystym wirtualnym destruktorem. Przed wyjaśnieniem wirtualnego destruktura musimy wiedzieć o konstruktorach, niszczycielach i dziedzictwie. W dziedzictwie dziedziczymy klasy po klasie rodzicielskiej. Zajęcia dzieci mogą być więcej niż jedną, ale klasa rodzica to tylko jedna. Wirtualne niszczyciele i czyste wirtualne niszczyciele są stosowane w dziedzictwie, aby oszczędzać od wycieku pamięci. Od podstawowego przykładu do zaawansowanego przykładu, omówiliśmy wszystko, co powinieneś wiedzieć, aby zacząć korzystać i wirtualnie zniszczyć pamięć klasy pochodnej.