Web - Amazon

We provide Linux to the World


We support WINRAR [What is this] - [Download .exe file(s) for Windows]

CLASSICISTRANIERI HOME PAGE - YOUTUBE CHANNEL
SITEMAP
Audiobooks by Valerio Di Stefano: Single Download - Complete Download [TAR] [WIM] [ZIP] [RAR] - Alphabetical Download  [TAR] [WIM] [ZIP] [RAR] - Download Instructions

Make a donation: IBAN: IT36M0708677020000000008016 - BIC/SWIFT:  ICRAITRRU60 - VALERIO DI STEFANO or
Privacy Policy Cookie Policy Terms and Conditions
Destruktor - Wikipedia, wolna encyklopedia

Destruktor

Z Wikipedii

Destruktor - w obiektowych językach programowania specjalna metoda, wywoływana przez program przed usunięciem obiektu i niemal nigdy nie jest wywoływana wprost w kodzie używającym obiektu. Pod względem funkcjonalnym jest to przeciwieństwo konstruktora.

Destruktor ma za zadanie wykonać czynności składające się na jego "zniszczenie", inne niż zwolnienie pamięci zajmowanej przez sam obiekt, przygotowujące obiekt do fizycznego usunięcia. Po jego wykonaniu obiekt znajduje się w stanie osobliwym i zazwyczaj nie można już z tym obiektem zrobić nic poza fizycznym usunięciem. Destruktor zwykle wykonuje takie czynności, jak zamknięcie połączenia z plikiem/gniazdem/potokiem, odrejestrowanie się z innych obiektów, czasem również zanotowanie faktu usunięcia, a także usunięcie obiektów podległych, które obiekt utworzył lub zostały mu przydzielone jako podległe (jeśli jest ich jedynym właścicielem) lub wyrejestrowanie się z jego użytkowania (jeśli jest to obiekt przezeń współdzielony).

W większości języków programowania (np. Object Pascal) destruktor jest dziedziczony jak każda inna metoda. Wiele obiektów nie musi mieć wcale destruktora, jeżeli poza zwolnieniem pamięci obiektu nie wymagają innych czynności i takie obiekty nazywamy trywialnie-destruowalnymi (ang. trivially-destructible). W takiej sytuacji wykorzystywany jest destruktor domyślny, tworzony automatycznie przez kompilator języka.

Istnienie destruktora i jego konstrukcja zależy od użytego języka programowania; choć w każdym języku obiekt musi być zniszczony pod koniec swojego życia, nie zawsze jest to oczywiste lub widoczne dla programisty, w niektórych językach istnieje mechanizm rozpoznawania czy obiekt jest używany i program automatycznie usuwa obiekty których nie używa inny obiekt. Tak nie jest np. w C++, ze względu na konieczność "ręcznego" zarządzania pamięcią, większość nietrywialnych klas musi posiadać jawne destruktory. Dla kontrastu, w Pythonie, gdzie normalnie nigdy nie ma miejsca jawny przydział zasobów, destruktory są rzadkością; można stworzyć nawet bardzo rozbudowane hierarchie klas bez napisania jednego destruktora. W praktyce destruktory wymagane są niemal wyłącznie w kodzie znajdującym się na styku Pythona i innego systemu lub języka, w którym wymagane jest jawne zarządzanie zasobami.

Spis treści

[edytuj] Wirtualność destruktora

W większości języków destruktor, tak jak każda metoda może być wirtualny. W wielu sytuacjach destruktor musi być wirtualny aby zapewnić prawidłowe wykorzystanie klasy, np. w C++ klasa musi mieć destruktor wirtualny kiedy zachodzi możliwość, że inna klasa będzie po niej dziedziczyła i będzie używany polimorfizm. Jest to możliwość dziedziczenia, nawet kiedy w danej chwili klasa nie ma żadnych potomków; w przeciwnym razie zachodzi konieczność zmiany deklaracji destruktora w momencie dodania klasy pochodnej, a to spowodowałoby zerwanie kompatybilności z już istniejącym kodem wykorzystującym tę klasę.

[edytuj] Oznaczanie destruktora

Destruktor:

  • w C++, C# i innych językach których składnia wzrorowana jest na C++, destruktor ma taką samą nazwę jak klasa, poprzedzoną tyldą [~] (dla odróżnienia od konstruktora)
  • w Pascalu destruktor jest metodą oznaczoną słowem kluczowym destructor

[edytuj] Przykładowy destruktor

W składni C++:

  class Samochod{
    public:
      string marka;
      //... (pewne dane i metody)
      ~Samochod() {
        std::cout << "Samochod " << marka << " zostal usuniety.\n";
      }
  };

Tu destruktorem jest ~Samochod(). W chwili usuwania obiektu, dokładnie przed zwolnieniem pamięci przeznaczonej dla obiektu jest wywoływany destruktor -- stąd też podczas usuwania danego samochodu zostanie wyświetlona linijka tekstu informująca o tym. Warto zwrócić uwagę, że powyższy przykład jest nieco sztuczny -- destruktor takiej postaci nie jest błędny, ale w rzeczywistych programach (poza momentem testowania powoływania i niszczenia obiektów) nie stosuje się destruktorów do drukowania komunikatów na ekranie.

[edytuj] Destruktor a wyciek pamięci

Ważnym zadaniem destruktora jest usuwanie podległych obiektów dynamicznych, które są mu przydzielone. Zapomnienie o tym może spowodować wycieki pamięci. Oto przykład klasy w C++, gdzie brak destruktora spowodowałby wyciek:

  class MojaKlasa {
    public:
      MojaKlasa()
        : liczba(new int) 
      {
        *liczba = 0;
      }
      ~MojaKlasa() {
        delete liczba;
      }
    private:
      int* liczba;
  };

Brak destruktora w tym przypadku spowoduje, że zostanie zwolniona pamięć przeznaczona obiekt w którym jest między innymi wskaźnik liczba, ale nie zostanie zwolniona pamięć na którą wskazuje liczba, gdyż zmienna ta jest oddzielnym elementem pamięci. Stąd też widać, że MojaKlasa nie jest klasą trywialnie niszczoną i destruktor domyślny nie jest wystarczający do prawidłowego usunięcia jej obiektów.

Powyższy przykład nie jest kompletną klasą, która działałaby prawidłowo w języku C++, gdyż brak jest konstruktora kopiującego. Nie został on jednak dodany ze względu na czytelność przykładu. Sposób przydzielenia pamięci dla zmiennej liczba.

[edytuj] Wirtualny destruktor - przykład

Przykład (błędny) w C++:

 #include <iostream>
  
 class A {
 public:
   virtual void metodaWirtualna() {
     std::cout << "w metodzie wirtualnej klasy A" ;      
   }
   ~A() {
     std::cout << "w destruktorze klasy A" ;
   }
 };
  
 class B : public A {
 public:
   int* wskaznik;
  
   B() {
     wskaznik = new int( 0 );
   }
   void metodaWirtualna() {
     std::cout << "w metodzie wirtualnej klasy B" ;      
   }
   ~B() {
     delete wskaznik;
     std::cout << "w destruktorze klasy B" ;
   }
 };
  
 int main(int argc, char *argv[]) 
 {
   A* wskaznikA = new B(); // możliwe, bo B jest klasą pochodną A
  
   wskaznikA->metodaWirtualna(); // poprawne zachowanie polimorficzne
   delete wskaznikA; // niepoprawne usunięcie obiektu klasy B
  
   return 0;
 }

W przykładzie tym występuje zmienna A typu "wskaźnik na A", ale przypisuje się jej wskazanie na obiekt typu B. Następnie wywołane są dwie metody: pierwsza, jawnie, to metodaWirtualna(), która poprawnie zachowuje się ze względu na rzeczywisty typ obiektu (B). Drugą z wywołanych metod jest destruktor - jego wywołanie ukryte jest wewnątrz operatora delete. Ponieważ utworzony obiekt jest klasy B, a wywołany jest destruktor klasy A, gdyż destruktor w klasie A nie został zadeklarowany jako wirtualny, obiekt nie zostanie prawidłowo zniszczony przed usunięciem.

Ten typ błędu programistycznego jest bardzo niebezpieczny i trudny do wykrycia, gdyż kompilator nie ostrzeże o niezgodności typów, skoro programista chce takiego użycia destruktora, zaś konsekwencje nieprawidłowego zniszczenia obiektu mogą być bardzo poważne, często powodując błędy w odległych, niezwiązanych z pierwotną przyczyną problemu, miejscach w programie.

Metody uniknięcia takiego nieprawidłowego zniszczenia obiektu:

  • Przestrzeganie zasady, aby klasy po których można dziedziczyć zawsze miały destruktor wirtualny.

[edytuj] Finalizator

W niektórych językach z wbudowanym odśmiecaczem (np. Java i C#) dostępna jest składnia finalizatora - specjalnej metody wywoływanej, gdy obiekt jest usuwany przy odśmiecaniu. W przeciwieństwie do destruktora nie wiadomo w którym dokładnie momencie działania programu to nastąpi.

Our "Network":

Project Gutenberg
https://gutenberg.classicistranieri.com

Encyclopaedia Britannica 1911
https://encyclopaediabritannica.classicistranieri.com

Librivox Audiobooks
https://librivox.classicistranieri.com

Linux Distributions
https://old.classicistranieri.com

Magnatune (MP3 Music)
https://magnatune.classicistranieri.com

Static Wikipedia (June 2008)
https://wikipedia.classicistranieri.com

Static Wikipedia (March 2008)
https://wikipedia2007.classicistranieri.com/mar2008/

Static Wikipedia (2007)
https://wikipedia2007.classicistranieri.com

Static Wikipedia (2006)
https://wikipedia2006.classicistranieri.com

Liber Liber
https://liberliber.classicistranieri.com

ZIM Files for Kiwix
https://zim.classicistranieri.com


Other Websites:

Bach - Goldberg Variations
https://www.goldbergvariations.org

Lazarillo de Tormes
https://www.lazarillodetormes.org

Madame Bovary
https://www.madamebovary.org

Il Fu Mattia Pascal
https://www.mattiapascal.it

The Voice in the Desert
https://www.thevoiceinthedesert.org

Confessione d'un amore fascista
https://www.amorefascista.it

Malinverno
https://www.malinverno.org

Debito formativo
https://www.debitoformativo.it

Adina Spire
https://www.adinaspire.com