2009-06-24 11 views
7

ich irgend Code (Delphi 7) mit folgenden Kontrolle ist Suche an der Spitze eines jeden Methodenaufrufes für ein bestimmtes Objekt:Warum sollten Sie in den Objektmethoden nach Zugewiesen (selbst) suchen?

if not Assigned(self) then 
    raise Exception.CreateRes(@sAbstractError); 

    { Real code for this method} 

Ich denke, dass dies mich von dem Versuch, eine Methode auf einem verhindern würde anrufen Null-Objektzeiger. Aber ich würde eine Ausnahme bekommen, sobald ich in diesem Fall versucht habe, auf die Mitgliedsdaten zuzugreifen, oder?

Ist das eine Art von Standard, die ich noch nie zuvor gesehen habe? Das betreffende Objekt stammt von TPersistent.

Antwort

8

Sie können eine Instanzmethode für einen Null-Zeiger aufrufen, obwohl dies nicht der Fall ist, den Sie absichtlich ausführen möchten. Wenn dies geschieht, wird die Ausführung ziemlich glücklich fortgesetzt, bis sie auf die Instanzdaten zugreifen muss und dann alles knallt.

In diesem Fall würde die Suche nach Nil Sie oben auf der Prozedur warnen, damit Sie etwas anderes tun können, wie beispielsweise das Protokollieren einer Stack-Ablaufverfolgung. Oder Sie könnten einen Breakpoint auf die Raise-Linie setzen, damit Sie hineintauchen und sehen können, was passiert.

Dh, es ist etwas, das ich tun könnte, wenn ich einen spezifischen Fehler hatte, den ich versuchte herauszufinden, wo eine Null-Referenz verwendet wurde.

Doing es regelmäßig scheint mich als Code-Geruch.

4

Es gibt Zugriffsverletzungsszenarien, die dazu führen können, dass Code im Speicher ausgeführt wird, in dem Self null ist. Einige Programmierer, anstatt das eigentliche Problem zu lösen, versuchen solche Behauptungen zu umgehen, um Korruption zu verhindern. Ich würde sehr gut prüfen, ob diese Ausnahme jemals in der Laufzeit erhöht, wenn ja - Sie haben buggy Code unter Ihren Händen.

Sie können den folgenden Artikel über das Thema lesen: When Self in Nil... You Know You are in Trouble.

Eine andere Möglichkeit bezieht sich auf Ereignisse, hier können Sie mehr lesen, mit vielen Beispielen für solche Tests und entsprechenden Erklärungen: Multicast Events - Part 2.

+2

Ich würde nicht sagen, dass dieser Beispielcode das eigentliche Problem überhaupt umgeht. Im Gegenteil, es hebt das Problem explizit hervor. –

10

Ein klarer Fehler, der sich über einen Nullzeiger beschweren kann, ist besser als eine Zugriffsverletzung, die nicht sagt, wie es passiert ist.

+1

+1 zum Abfangen eines Null-Zeigers statt einer * möglichen * Zugriffsverletzung. –

+0

Also sagen Sie, dass Sie alle Ihre Objekte auf diese Weise codieren? –

+0

Es ist sehr schwer für eine Nullzeiger-Dereferenzierung, nicht zu boomen. Sie besitzen nicht den Speicher dort unten. –

1

Und dann gibt es immer die Möglichkeit, dass der Code nicht abstürzen würde, wenn er mit nil Self läuft. Beispiel - wenn es nicht auf Felder des Eigentümerobjekts zugreift. In diesem Fall würde dieser Test das Problem auffangen, das andernfalls unentdeckt bleiben würde.

Dennoch nimmt das defensive Programmierung auf die Spitze. Ich nie (OK, fast nie - nur wenn ich Wabbits jage ... errr ... Quetschen von Käfern) tu das.

+0

Obwohl ich es getan habe - es ist eine schlechte Form, eine Nicht-Klassen-Methode zu verwenden, als wäre es eine Klassenmethode. –

1

Scheint die ursprüngliche Absicht für diese Methode ist, dass es eine abstrakte Methode wird.

3

Dies ist eine Gelegenheit, die definitiv zu einem Absturz führen sollte (d. H. Eine OS-Ausnahme wie "Lesen von Adresse 0x00000000"). Eine Sprachausnahme zu werfen ist einfach überflüssig (und es ist nicht sinnvoll, EAbstractError hier zu missbrauchen).

Die Überprüfung auf gültige Eingabeparameter ist in einer unsicheren Sprache keine praktikable Aufgabe, da Sie nie Gewissheit erlangen werden und Ihre Handhabung ungültiger Parameter daher niemals konsistent sein wird. (Warum werfen Sie eine Exception, wenn ein Null-Zeiger übergeben wird, aber nicht für 0x00000001, was genauso ungültig ist?). Für eine technische Diskussion dieser Frage lesen Sie Larry Osterman's Blog über why not to check for valid pointers.

Eine Ausnahme sollte beachtet werden: in Delphi kann die Free Methode auf einen Null-Zeiger aufgerufen werden, was natürlich diese Art der Überprüfung erfordert.

Verwandte Themen