In Object Pascal werden alle Objekte im Heap-Bereich des Speichers und nicht auf dem Stapel erstellt, sodass der Konstruktor nicht wie in C++ automatisch vom Compiler aufgerufen wird. Das Konstruieren und Zerstören von Objekten liegt in der Verantwortung des Programmierers.
Um ein Objekt zu erstellen, müssen Sie zunächst Speicher für das Objekt zuweisen. Dieser Schritt wird vom Compiler in Object Pascal unterstützt – der sogenannten „Compiler Magic“. Magic)“ muss der Programmierer an diesem Prozess nicht teilnehmen; dann müssen die Datenelemente des Objekts initialisiert werden, und der Compiler ist dafür verantwortlich, sie zu „löschen“, aber wenn es eine spezielle Zuweisung gibt, kann diese abgeschlossen werden Im Konstruktor müssen die angeforderten Ressourcen (nicht der vom Objekt selbst belegte Speicher) freigegeben werden. Diese Aufgaben liegen ebenfalls in der Verantwortung des Destruktors „Compiler-Magie“.
Zuweisung und Recycling von Objektspeicher
Wenn der Compiler einem Objekt Speicher zuweist, besteht die von ihm bereitgestellte Unterstützung darin, diese Zeilen Assemblercode einzufügen, bevor der Konstruktor aufgerufen wird:
test dl, dl
jz +08 $
füge hinzu, insbesondere -$10
call @ClassCreate // Achten Sie auf diese Codezeile
Die letzte Zeile des obigen Codes ruft die Funktion _ClassCreate in Zeile 8949 der Datei system.pas auf (vorbehaltlich Delphi 6). Diese Funktion weist jedem Objekt speziell den entsprechenden Speicher zu. Nachdem die Speicherzuweisung abgeschlossen ist, wird der Konstruktor der Klasse aufgerufen, um die Datenelemente zu initialisieren. Anschließend fügt der Compiler die folgenden Zeilen Assemblercode ein:
test dl, dl
jz +$0f
Rufen Sie @AfterConstruction an
pop dWord ptr fs:[$00000000]
füge insb. $0c hinzu
Die Hauptaufgabe besteht darin, AfterConstruction für jede Objektinstanz aufzurufen. Dieser Aufruf ist in Delphi nutzlos. Seine Existenz ist C++Builder vorbehalten.
Ebenso muss beim Zerstören eines Objekts zunächst der Destruktor der Klasse aufgerufen werden, um die vom Objekt angeforderten Ressourcen freizugeben. Danach wird der vom Objekt selbst belegte Speicherplatz recycelt. Diese Arbeit wird dadurch abgeschlossen, dass der Compiler nach dem Aufruf des Destruktors den folgenden Assemblercode einfügt:
Rufen Sie @BeforeDestruction auf
test dl, dl
jle +05 $
Rufen Sie @ClassDestroy an
Die von diesen Codes geleistete Arbeit entspricht der Arbeit beim Erstellen des Objekts und beim Zuweisen von Speicher, hauptsächlich beim Aufrufen der Funktion _ClassDestroy in Zeile 8997 in system.pas.
Konstruktor und Destruktor
Um einen Konstruktor zu definieren, verwenden Sie das Schlüsselwort Constructor. Konventionell lautet der Name des Konstruktors Create (natürlich können auch andere Namen verwendet werden, aber das ist keineswegs ein gutes Design!). wie:
Typ
TMyFamily = class // Die für Ihre Familie definierte Klasse
Privat
FMyFatherName : String; // der Name deines Vaters
FMyMotherName : String; // der Name deiner Mutter
… // Andere Mitglieder Ihrer Familie
Öffentlich
Konstruktor Create(strFatherName, strMotherName : String);
…… // Andere Methoden
Ende;
Sie fragen sich vielleicht: Können ihre Objekte erstellt werden, wenn ich keinen Konstruktor für meine Klasse bereitstelle? Die Antwort lautet: Ja. Der Grund wurde bereits erwähnt: Die Zuweisung des vom Objekt selbst belegten Speichers wird vom Compiler abgeschlossen. Und da in Object Pascal alle Klassen (außer der TObject-Klasse selbst) von der TObject-Klasse abgeleitet sind, ruft der Compiler den TObject.Create()-Konstruktor auf, aber diese Funktion ist eine leere Funktion und hat keinen Einfluss auf die TMyFamily-Klasse . Wenn die Datenelemente (FMyFatherName, FMyMotherName) initialisiert werden, werden sie automatisch in leere Zeichenfolgen (z. B. '') gelöscht, da TObject.Create() Ihren Vater oder Ihre Mutter überhaupt nicht kennt!
Beim Erstellen eines Objekts wird der Konstruktor direkt aufgerufen, und zwar in der folgenden Form:
MyFamilyObject := TMyFamily.Create('Zhang', 'Li');
Verwenden Sie das Schlüsselwort Destructor, um einen Destruktor zu definieren. Konventionell heißt der Destruktor Destroy. wie:
Typ
TMyClass = Klasse
Öffentlich
Destruktor Destroy(); override;
Ende;
Der Grund, warum die Override-Anweisung am Ende der Destruktordeklaration hinzugefügt wird, besteht darin, sicherzustellen, dass das Objekt im Fall von Polymorphismus korrekt zerstört werden kann (Polymorphismus wird in Abschnitt 2.4 ausführlich besprochen). Wenn Sie das Schlüsselwort „override“ nicht hinzufügen, gibt der Compiler eine Warnung ähnlich der „Methode „Destroy“ verbirgt die virtuelle Methode des Basistyps „TObject““ aus. Die Warnung bedeutet, dass das von Ihnen definierte Destroy die virtuelle Methode TObject.Destroy() der Basisklasse verbirgt. In diesem Fall kann das Objekt in polymorphen Situationen nicht korrekt zerstört werden.
Hinweis: Destruktoren müssen mit einer Override-Anweisung deklariert werden.
Wenn in Ihrer Klasse keine speziellen Ressourcen freigegeben werden müssen, müssen Sie auch keinen Destruktor definieren. Wenn Sie jedoch ein Objekt zerstören, sollten Sie die Free()-Methode des Objekts aufrufen, anstatt Destroy() direkt aufzurufen.
MyFamilyObject.Free();
Dies liegt daran, dass die Free()-Methode ermittelt, ob das Objekt selbst Null ist. Wenn dies nicht der Fall ist, wird Destroy() des Objekts aufgerufen, um die Sicherheit zu erhöhen. Da es nun sicherere Möglichkeiten gibt, dies zu tun, gibt es sicherlich keinen Grund, es nicht zu tun.
Hinweis: Rufen Sie Destroy() niemals direkt für ein Objekt auf, sondern Free().
Daraus lässt sich schließen, dass Sie in Object Pascal nur auf die Zuweisung und Freigabe der vom Objekt beanspruchten Ressourcen achten müssen und sich nicht um den vom Objekt selbst belegten Platz kümmern müssen!