Über die Zuweisung und Wiederverwendung von Objektspeicher
Ich weiß nicht, ob jemand eine Idee hat, das DL-Register hier zu platzieren. Wenn nicht, denken Sie einfach darüber nach, es wird Ihnen gut gehen. Tatsächlich gibt es vor dem folgenden Code (1) eine solche Codezeile MOV dl, 1. Warum ist das so? Der Grund ist nicht ganz einfach, die Wiederverwendung des Codes. Zur Verwendung des DL-Registers gibt es hier eine Einführung in die Hilfe von Delphi. Wenn Sie es finden, werden Sie ein Meister sein. Hier geht es darum, zu lernen, nein, angeln zu lernen, nicht um Fisch zu bitten. Borland sagte Folgendes: „Ich verwende das DL-Register, um ein Flag zu speichern. Wenn der Wert 1 ist, werde ich das Objekt erstellen. Andernfalls werde ich das Objekt nicht erstellen, wenn Sie etwas unklar sind, denken Sie noch einmal darüber nach.“ wieder. Wenn Sie Ihre Augen noch nicht geöffnet haben, schauen Sie sich den folgenden Code (2) an. Sagen Sie nicht, dass Sie ihn nicht gefunden haben. Husten, was ist los? Ich rede ständig Unsinn, ich verspreche, es nicht zu sagen wieder.
{Code (1)
test dl, dl
jz +08 $
füge hinzu, insbesondere -$10
Aufruf @ClassCreate }
{///Code (2)
PROcedure Tapplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var
Instanz: TComponent;
beginnen
//////// Instance := TComponent(InstanceClass.NewInstance);
TComponent(Reference) := Instance;
versuchen
//////// Instance.Create(Self);
außer
TComponent(Reference) := nil;
erheben;
Ende;
if (FMainForm = nil) und (Instance is TForm) then
beginnen
TForm(Instance).HandleNeeded;
FMainForm := TForm(Instanz);
Ende;
Ende;
}
In diesem Fall ruft Delphi Code (1) auf, wenn die Instanz der erstellten Klasse zum ersten Mal aufgerufen wird. Wenn dann jemand die Create-Methode aufrufen muss, dann ist es nur der Compiler wie dieses MOV dl, 0, damit die Sprunganweisung „Urteil 0“ im Code (1) an die Stelle gelangt, an der sie hingehört (Warum redest du schon wieder Unsinn? Das letzte Mal, das verspreche ich.) Tatsächlich ist die Create-Methode hier nur eine gewöhnliche Methode und sollten Sie auch beachten, dass der erste Aufruf der Create-Methode oder NewInstance-Methode die Klasse ist, die diese Nachricht sendet (beachten Sie, dass diese Nachricht nicht gesendet wird). Windows-Nachricht, diese Nachricht ist nicht die andere Nachricht, haha, es ist wieder Unsinn, es ist wirklich das letzte Mal, es ist wahr. Wenn Sie die Nachricht hier nicht verstehen, lernen Sie bitte sorgfältig die Kenntnisse über Objektorientierung und Modellierung) und rufen Sie an es später. Die Create-Methode ist ein etabliertes Objekt, Instance.Create(Self); denken Sie darüber nach, natürlich hat sich der Wert des dl-Registers geändert.
Okay, ich habe nicht viel Zeit. Abschließend möchte ich noch etwas zur Flagge (Taiwans Übersetzungsmethode, ich finde dieses Wort gut, ich schlage vor, dass Sie es auch verwenden, um mir später viel Ärger zu ersparen) hinzufügen Anweisungen zur Verwendung dieses DL-Registers sollten nicht geändert werden. Wenn Sie genau darüber nachdenken, hat sich Delphi nicht von 1 auf 6 geändert. Dies beweist übrigens auch, dass der HB-Designer von Delphi ein ist Charakter. Natürlich kann ich nicht vergleichen. Haha, es geht wieder los, okay, ich höre auf zu reden. Lassen Sie mich abschließend sagen, dass die TObject.Create-Methode keineswegs eine leere Methode ist. Denken Sie daran und denken Sie dann darüber nach.
Okay, andere Dinge, schauen Sie sich diese bitte persönlich an. In diesem Fall werden Sie viel gewinnen.
„Verschwinde von hier, ich will es sehen und darüber nachdenken, und ich will deinen Unsinn nicht!“ :) :)
Tschüss
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!