オブジェクトメソッドでAssigned(self)をチェックするのはなぜですか?
質問
特定のオブジェクトのすべてのメソッド呼び出しの先頭に次のチェックがあるコード(Delphi 7)を探しています:
if not Assigned(self) then
raise Exception.CreateRes(@sAbstractError);
{ Real code for this method}
これにより、nullオブジェクトポインターでメソッドを呼び出そうとするのを防ぐことができると思います。しかし、とにかくその場合、メンバーデータにアクセスしようとするとすぐに例外が発生します。
これは、これまで見たことのないタイプの標準ですか?問題のオブジェクトはTPersistentから派生しています。
解決
nullポインターでインスタンスメソッドを呼び出すことはできますが、意図的にやりたいことではありません。それが発生すると、インスタンスデータにアクセスする必要があるまで実行は非常に楽しく続けられ、その後すべてが実行されます。
その場合、nilをチェックすると、手順の先頭で警告が表示されるので、スタックトレースのログ記録などの別の操作を行うことができます。または、レイズラインにブレークポイントを設定して、飛び込んで何が起きているかを確認することもできます。
つまり、nil参照が使用されている場所を追跡しようとしていた特定のバグがあった場合、私はそれを行うことができます。
定期的にそれを行うと、コードの匂いがする。
他のヒント
nilポインターについて文句を言う明確なエラーは、それがどのように発生したかを言わないアクセス違反よりも優れています。
Selfがゼロのメモリで実行されるコードにつながる可能性のあるアクセス違反シナリオがあります。一部のプログラマーは、実際の問題を解決する代わりに、そのようなアサーションを使用して、種類の破損を防ぐことを回避しようとします。実行時に例外が発生するかどうかを非常によく確認します。もしそうなら、手元にバグのあるコードがあります。
このテーマに関する次の記事を読むことができます。問題が発生しています。
別の可能性はイベントに関連しています。詳細については、そのようなテストの例と対応する説明を参照してください:マルチキャストイベント-パート2 。
これは、クラッシュ(つまり、「アドレス0x00000000からの読み取り」などのOS例外)につながるはずの機会です。言語例外をスローすることは単に冗長です(そして、ここでEAbstractErrorを誤用しても改善されません)。
有効な入力パラメーターの確認は、確実性が得られないため、安全でない言語では実行可能なタスクではありません。したがって、無効なパラメーターの処理に一貫性がありません。 (なぜnilポインターが渡されたときに例外をスローしますが、0x00000001に対しては例外をスローしますか?この質問のより技術的な議論については、に関するLarry Ostermanのブログをご覧ください。有効なポインターをチェックしない理由。
1つの例外に注意する必要があります。Delphiでは、nilポインターで Free
メソッドを呼び出すことができます。もちろん、このようなチェックが必要です。
そして、nil Selfで実行してもコードがクラッシュしない可能性が常にあります。例-所有者オブジェクトのフィールドにアクセスしていない場合。その場合、このテストは検出されない問題をキャッチします。
それでも、それは防御的なプログラミングを極端に取っています。私は決して(ほとんど、決して-ウサギを狩っているときだけ...えーっと...バグをつぶす)それをしません。
そのメソッドの本来の意図は、抽象メソッドになることです。