Sollte das Aufrufen von Free für einen Objektverweis, der auf "nil" gesetzt ist, nicht jedes Mal, wenn er aufgerufen wird, eine Zugriffsverletzung auslösen?

7

Ich bekomme Zugriffsverletzungen von der Unit DBXCommon.pas (in Delphi XE). Wenn ich mir den Code ansehe, sehe ich Dinge wie die folgenden (an den Ausrufezeichen):

%Vor%

Aber ich sehe Konstrukte wie diese (zuerst zuweisen Nil, dann ein Free) viel mehr in DBXCommon.pas . Ist das ein Konstrukt, das ich nicht kenne, oder verursacht das wirklich eine Zugriffsverletzung jedes Mal, wenn dieser Codeabschnitt aufgerufen wird?

    
Geerten 21.12.2011, 14:19
quelle

3 Antworten

15

Der Aufruf von Free für eine Nullreferenz ist immer sicher. Gehen Sie in die Implementierung von TObject.Free , um zu sehen, warum.

Dieser Code ist ein Beispiel für eine Factory-Funktion . Seine Aufgabe besteht darin, eine neue Instanz einer Klasse zu erstellen. Wenn dies jedoch fehlschlägt, muss sichergestellt werden, dass beim Erstellen einer Ausnahme keine halb erstellte Instanz verloren geht. Daher wird Free aufgerufen. Wenn es sicher ist, dass es erfolgreich sein wird, überträgt es den Besitz des Ergebnisses an den Aufrufer. Es ruft immer noch Free auf, aber wenn es bereits Eigentum übertragen hat, ruft es Free für eine Nullreferenz auf, und es wird kein Schaden angerichtet. Dieser Code überträgt den Besitz:

%Vor%

Die Art und Weise, wie I eine Factory-Funktion schreiben würde, würde die separate Variable Connection überflüssig machen. Ich würde das Ergebnis direkt in Result konstruieren, aber es freilassen, wenn es eine Ausnahme wie diese geben würde:

%Vor%

Das hat den gleichen Effekt.

    
Rob Kennedy 21.12.2011, 14:25
quelle
6

Es ist sicher, Free auf nil referenz aufzurufen, während die Implementierung nach Self <> nil sucht, bevor Destroy aufgerufen wird. Siehe die Erklärung von Allen Bauer im Embarcadero-Forum , warum TObject.Free eingeführt wurde. Ich füge hier nur das relevante Zitat ein:

  

Der einzige Grund für die Einführung der nicht-virtuellen Free-Methode in TObject war die Verwendung in Destruktoren als einfache Abkürzung für:

%Vor%     
ain 21.12.2011 14:24
quelle
4

TObject.Free wird grundsätzlich als if Self <> nil then Destroy implementiert, daher sollte der obige Code keine Ausnahme auslösen.

    
Andreas Rejbrand 21.12.2011 14:24
quelle

Tags und Links