Kürzlich sah ich einen Internetnutzer im Internet fragen: Wie kann festgestellt werden, ob ein Objektzeiger verfügbar ist? Mit anderen Worten: Wie kann festgestellt werden, ob ein Objektzeiger auf eine tatsächlich verwendbare Objektinstanz zeigt? Eigentlich sollte das kein Problem sein. Denn der Programmierer sollte in der Lage sein, sein Programm so zu steuern, dass es nicht auf einen ungültigen Zeiger zugreift, da die Erstellung und Zerstörung aller Objektinstanzen unter seiner Kontrolle liegt. Und selbst wenn es keine direkte Möglichkeit gibt, festzustellen, ob der Objektzeiger verfügbar ist, kann dies auch auf andere indirekte Weise erfolgen (z. B. mithilfe einiger Bezeichner usw.) (z. B. wenn wir eine Objektinstanz zerstören, legen wir fest). (der Zeiger des Objekts, auf das der Zeiger ist, ist Null). Aber wenn wir die beiden oben genannten Punkte beiseite legen und einfach untersuchen, ob es eine Möglichkeit gibt, festzustellen, ob ein Objektzeiger in Delphi verfügbar ist, was passiert dann?
In Object Pascal kann eine Klasse zwei Arten von Methoden haben, eine heißt Objektmethode (Objektmethode) und die andere ist Klassenmethode (Klassenmethode). Die sogenannte Objektmethode bedeutet, dass die Definition der Methode für ein Objekt (oder eine Instanz) gilt, sodass der Aufruf der Methode auf einem Objekt (oder einer Instanz) basieren muss. Beispielsweise ist der Destruktor einer Klasse ein Objekt Methode (tatsächlich verwenden wir häufig die meisten Methoden Objektmethoden). Die Klassenmethode bezieht sich auf die Definition der Methode basierend auf einer Objektklasse, sodass der Aufruf der Methode nicht auf einer bestimmten Objektinstanz basieren muss, z. B. auf dem Konstruktor „Create“ der Klasse. Das hat einige Inspiration für uns. Die Feststellung, ob ein Objektzeiger verfügbar ist, scheint durch die folgenden Schritte erreicht zu werden. Zuerst können wir feststellen, ob der Objektzeiger Null ist. Wenn ja, dann ist er definitiv nicht verfügbar. Wenn nicht, versuchen wir, eine Objektmethode des Objekts auszuführen, um zu sehen, ob es Ausnahmen wie einen ungültigen Speicherzugriff gibt. Dies wird verwendet, um festzustellen, ob das Objekt verfügbar ist. Verwenden Sie den folgenden Code, um unsere Idee zu überprüfen:
var
Obj: TObject;
beginnen
Obj := TObject.Create; //1
Obj.Free; //2. Geben Sie das gerade erstellte Objekt frei und der Speicher wird zu diesem Zeitpunkt recycelt
Wenn Obj = Null, dann //3. Bestimmen Sie, ob der Zeiger leer ist (dieser Schritt ist oft erfolglos, weil das Objekt
//wird freigegeben, Delphi leert den Objektzeiger nicht automatisch)
ShowMessage('Objektzeiger ist nicht verfügbar.')
anders
beginnen
Versuchen
Wenn Obj.ClassType = TObject, dann //4. Rufen Sie eine Objektmethode von TObject auf
ShowMessage('Der Objekttyp ist TObject');
Außer
ShowMessage('Objektzeiger ist nicht verfügbar.')
Ende;
Ende;
Ende;
Wenn wir den obigen Code ausführen, stellen wir fest, dass Obj.ClassType auch dann noch verfügbar ist, wenn Obj.Free ausgeführt wurde. Dies zeigt, dass nicht alle Objektmethoden von einer Objektinstanz abhängig sein müssen, um zugänglich zu sein. Der Grund dafür ist, dass diese Objektmethode nicht auf den von einer Objektinstanz angeforderten Speicher zugreifen muss. In diesem Sinne sieht die TObject.ClassType-Methode nicht wie eine echte Objektmethode aus, sondern ähnelt eher einer Klassenmethode.
Wenn wir den obigen Code ausführen, können wir auch feststellen, dass ein Objekt, wenn es die Free-Methode ausführt, nur den gesamten Speicher freigibt, den es bei seiner Erstellung beantragt hat, sich jedoch nicht auf den Wert des Objektzeigers selbst auswirkt. Der Objektzeiger zeigt weiterhin auf die ursprüngliche Speicheradresse. Aufgrund der Besonderheiten der Implementierung einiger Objektmethoden (z. B. ClassType) ist das Ergebnis des Objektmethodenaufrufs auch dann noch korrekt, wenn das Objekt freigegeben wurde.
Zusammenfassend können wir eine Schlussfolgerung ziehen: Ob ein Objektzeiger als verfügbar beurteilt werden kann, hängt davon ab, ob die Klasse, zu der der Objektzeiger gehört, eine Möglichkeit bietet, auf den Objektinstanzspeicher zuzugreifen – auf diese Weise können auch Methoden verwendet werden Eigenschaften sein. Wie ist nun die Situation konkret in den einzelnen Kategorien?
TObject, diese Klasse ist die Vorfahrenklasse aller Klassen, es gibt keine Möglichkeit, ein Urteil zu fällen.
TPersistent, abgeleitet von TObject, muss beim Erstellen einer Objektinstanz keinen zusätzlichen Speicher beantragen, daher gibt es keine Möglichkeit, dies zu beurteilen.
TComponent, abgeleitet von TPersistent, fügt viele Eigenschaften hinzu, die beim Erstellen einer Objektinstanz die Anwendung von zusätzlichem Speicher erfordern, sodass dies theoretisch beurteilt werden kann. Der Code lautet wie folgt:
function ComponentExists(AComponent: TComponent): Boolean;
beginnen
versuchen
AComponent.Hasparent; //Hinweis: Dieser Satz kann auch „AComponent.Tag;“ sein
//Oder „AComponent.Name“
Ergebnis := True;
außer
Ergebnis := Falsch;
Ende;
Ende;
Durch den Aufruf von ComponentExists können wir feststellen, ob ein Objektzeiger vom Typ TComponent verfügbar ist, unabhängig davon, ob der Objektzeiger freigegeben oder auf Null gesetzt wurde.
Für andere Klassen wie TControl, TWinControl oder TButton usw. gilt weiterhin die Beurteilungsmethode von TComponent, sofern sie von TComponent abgeleitet sind.
Es gibt andere benutzerdefinierte Klassen, die direkt von Klassen abgeleitet sind, die nicht beurteilt werden können (z. B. TObject und TPersistent), aber es gibt keine Attribute, die während der Instanziierung eine Speicheranwendung erfordern ist möglich. An einem Beispiel:
Angenommen, wir haben eine TPerson-Klasse, die wie folgt definiert ist:
TPerson = Klasse(TObject)
Privat
FSex: TSex; // TSex ist das Geschlecht des Aufzählungstyps;
FFirstName: String;
FLastName: String;
//…
Öffentlich
Eigenschaft Sex: TSex lesen FSex schreiben FSex;
Eigenschaft FirstName: String read FFirstName write FFirstName;
Eigenschaft LastName: String read FLastName write FLastName;
//…
Ende;
Anschließend können Sie für den Zeiger Person vom Typ TPerson den folgenden Code verwenden, um zu ermitteln, ob der Zeiger verfügbar ist:
Versuchen
Person.Sex;
//Oder Person.FirstName;
//Oder Person.LastName;
result := True; //Der Zeiger ist verfügbar
Außer
result := False;//Der Zeiger ist nicht verfügbar
Ende;
Was wir oben besprochen haben, ist nur eine technische Möglichkeit. Der Punkt, den ich betonen möchte, ist, dass es nicht dazu ermutigt wird, es häufig zu tun, auch wenn es eine gute Möglichkeit gibt, dies zu tun. Denn ein Programm mit strenger Logik sollte in der Lage sein, den Zugriff auf einen ungültigen Zeiger zu verhindern.
Weitere Artikel