Destruktor (Computerprogrammierung) - Destructor (computer programming)

Bei der objektorientierten Programmierung ist ein Destruktor (manchmal abgekürzt dtor ) eine Methode, die mechanisch aufgerufen wird, kurz bevor der Speicher des Objekts freigegeben wird. Dies kann passieren, wenn seine Lebensdauer an den Gültigkeitsbereich gebunden ist und die Ausführung den Gültigkeitsbereich verlässt, wenn er in ein anderes Objekt eingebettet ist, dessen Lebensdauer endet, oder wenn er dynamisch zugewiesen und explizit freigegeben wurde. Sein Hauptzweck besteht darin, die Ressourcen (Speicherzuweisungen, geöffnete Dateien oder Sockets, Datenbankverbindungen , Ressourcensperren usw.), die das Objekt während seiner Lebensdauer erworben hat, freizugeben und / oder von anderen Entitäten abzumelden, die möglicherweise Verweise darauf behalten. Die Verwendung von Destruktoren ist für den Prozess der Ressourcenerfassung ist Initialisierung (RAII) erforderlich .

Bei den meisten Arten von automatischen Garbage Collection- Algorithmen kann die Freigabe des Speichers lange nach dem Erreichen des Objekts erfolgen, sodass Destruktoren ( in diesem Fall als Finalizer bezeichnet ) für die meisten Zwecke ungeeignet sind. In solchen Sprachen erfolgt die Freigabe von Ressourcen entweder über ein lexikalisches Konstrukt (z. B. try..finally, Pythons "with" oder Javas "try-with-resources"), das RAII entspricht, oder explizit durch Aufrufen von a Funktion (entspricht dem expliziten Löschen); Insbesondere verwenden viele objektorientierte Sprachen das Dispose-Muster .

Destruktorsyntax

  • C ++ : Destruktoren haben denselben Namen wie die Klasse, der sie zugeordnet sind, jedoch ein Tilde- Präfix (~).
  • D : Destruktoren werden mit dem Namen deklariert ~this() (während Konstruktoren mit deklariert werden this() ).
  • Object Pascal : Destruktoren haben das Schlüsselwort destructor und können benutzerdefinierte Namen haben, werden jedoch meistens benannt Destroy .
  • Ziel-C : Die Destruktormethode hat den Namen dealloc .
  • Perl : Die Destruktormethode hat einen Namen DESTROY . In der Systemerweiterung des Elchobjekts wird es benannt DEMOLISH .
  • PHP : In PHP 5+ hat die Destruktormethode einen Namen __destruct . In früheren Versionen von PHP gab es keine Destruktoren.
  • Python : Es gibt __del__ Methoden, die im Python 2-Sprachhandbuch als Destruktoren bezeichnet werden, aber sie sind tatsächlich Finalisierer, wie in Python 3 anerkannt.
  • Rost : Die Destruktormethode für Rost hat den Namen drop
  • Swift : Die Destruktormethode hat den Namen deinit .

In C ++

Der Destruktor hat denselben Namen wie die Klasse, jedoch mit einer Tilde (~) davor. Zum Beispiel hat eine Klasse namens foo den Destruktor . Außerdem haben Destruktoren weder Parameter noch Rückgabetypen. Wie oben angegeben, wird ein Destruktor für ein Objekt immer dann aufgerufen, wenn die Lebensdauer des Objekts endet. Wenn das Objekt als automatische Variable erstellt wurde , endet seine Lebensdauer und der Destruktor wird automatisch aufgerufen, wenn das Objekt den Gültigkeitsbereich verlässt. Da C ++ keine Garbage Collection hat, wird der Destruktor aufgerufen , wenn das Objekt mit einer Anweisung (dynamisch auf dem Heap ) erstellt wurde, wenn der Operator auf einen Zeiger auf das Objekt angewendet wird. Normalerweise findet diese Operation in einem anderen Destruktor statt, normalerweise im Destruktor eines Smart-Pointer- Objekts. ~foo()newdelete

In Vererbungshierarchien stellt die Deklaration eines virtuellen Destruktors in der Basisklasse sicher, dass die Destruktoren abgeleiteter Klassen ordnungsgemäß aufgerufen werden, wenn ein Objekt über einen Zeiger auf die Basisklasse gelöscht wird. Objekte, die auf diese Weise gelöscht werden können, müssen einen virtuellen Destruktor erben.

Ein Destruktor sollte niemals eine Ausnahme auslösen.

Beispiel

#include <cstring>
#include <iostream>

class Foo {
public:
    Foo(): data_(new char[sizeof("Hello, World!")]) {
        std::strcpy(data_, "Hello, World!");
    }

    Foo(const Foo& other) = delete;             // disable copy construction
    Foo& operator=(const Foo& other) = delete;  // disable assignment

    ~Foo(void) { delete[] data_; }

private:
    friend std::ostream& operator<<(std::ostream& os, const Foo& foo) {
        os << foo.data_;
        return os;
    }

    char* data_;
};

int main() {
    Foo foo;
    std::cout << foo << std::endl;
}

Objekte, die nicht sicher kopiert und / oder zugewiesen werden können, sollten aus dieser Semantik entfernt werden, indem ihre entsprechenden Funktionen innerhalb einer öffentlichen Kapselungsebene als gelöscht deklariert werden. Eine ausführliche Beschreibung dieser Methode finden Sie in Scott Meyers populärem Buch Effective Modern C ++ (Punkt 11: "Bevorzugen Sie gelöschte Funktionen gegenüber privaten undefinierten.").

In C mit GCC-Erweiterungen

Die GNU Compiler Collection ‚s C - Compiler kommt mit 2 - Erweiterungen , die Umsetzung Destruktoren ermöglichen:

  • Mit dem destructor Funktionsattribut können global priorisierte Destruktorfunktionen definiert werden: Bei der main() Rückgabe werden diese Funktionen in der Prioritätsreihenfolge aufgerufen, bevor der Prozess beendet wird. Siehe auch: Die Kunst der Ausbeutung hacken .
  • Das Attribut " Bereinigungsvariable" ermöglicht das Anhängen einer Destruktorfunktion an eine Variable: Die Funktion wird aufgerufen, wenn die Variable den Gültigkeitsbereich verlässt.

Xojo

Destruktoren in Xojo (REALbasic) können in einer von zwei Formen vorliegen. Jedes Formular verwendet eine reguläre Methodendeklaration mit einem speziellen Namen (ohne Parameter und ohne Rückgabewert). Das ältere Formular verwendet denselben Namen wie die Klasse mit dem Präfix ~ (Tilde). Das neuere Formular verwendet den Namen Destructor . Die neuere Form wird bevorzugt, da sie das Refactoring der Klasse erleichtert.

Class Foobar
  // Old form
  Sub ~Foobar()
  End Sub

  // New form
  Sub Destructor()
  End Sub
End Class

Siehe auch

Verweise