質問
まずこの作品のコードという理由に破損がない this
は null
.んくうことができ null
では通常のメソッドの呼び出しなど
myObject->func();
内部 MyObject::func()
ていま
if (!this) { return false; }
その最初の行を投げ飛ばす NullPointerException
代わりに内部の null
(?) 方法は?
解決
あなたがお持ちの場合:
MyObject *o = NULL;
o->func();
次に何が起こるかはfunc
仮想であるかどうかに依存します。もしそうであれば、それはからのvtableを取得するためのオブジェクトを必要とするため、それは、クラッシュします。しかし、それはNULLに設定され、このポインタでコールが進む仮想ない場合ます。
私は、標準的には、これは「未定義の動作」であるので、何が起こる可能性がありますが、代表的なコンパイラだけでポインタがNULLであるかどうかをチェックしないためのコードを生成すると言うと信じています。いくつかのよく知られたライブラリは、私が説明した動作に依存:MFCはNULLポインタで呼び出すことができSafeGetHandle
のようなものと呼ばれる機能があり、その場合にはNULLを返します。
あなたは、再利用可能なヘルパー関数を書きたいかもしれません。
void CheckNotNull(void *p)
{
if (p == NULL)
throw NullPointerException();
}
あなたが、その後を含め、すべての引数をチェックするための関数の開始時にそれを使用することができます。this
:
CheckNotNull(this);
他のヒント
トラップする方法(設計によって)エラーのこれらの種類は、ヌルポインタ引数で作成時にスローポインタラッパークラス(shared_ptr
に似ている)を使用しています。間接参照する場合それはまた投げるかもしれないが、それは少し遅 - 何もないよりはまし、私は推測する。
if(this == null)
throw new NullPointerException;
if(!this)
return false;
(==NULL)が未定義の動作に応じます。いという思いを大切にしていけることができるのはこのチェック)
として、以下の呼び出し:
((CSomeClass*) 0)->method();
の動作は未定義だと思うが、なぜわざわざ、これをチェックして下さい==NULL CSomeClass::方法は?
編集: なっているのでしょうかコンパイラ対応(0==この組み合わせて使用しない場合はメンバ変数がどこで見つ仮想テーブルのポインター?この場合、このクラスでは使用しないでpolymoprhism.
this
がNULLであるためには、それは可能です。私は、このコードは(ひどく)オブジェクトがまだ初期化されて終了していない競合状態を検出しようとしている、または削除されたと思われる。
このポインタは、このような場合にはnullになることができます:
class Test
{
public:
bool f();
private:
int m_i;
};
bool Test::f()
{
if(!this)
{
return false;
}
m_i = 0;
return true;
}
int main(int argc, char **argv)
{
Test* p = new Test;
delete p;
p = NULL;
p->f();
}
私は、誰かがアクセス違反の例外を避けるために、迅速なハックをしたと思います。
この==ヌルにのみ発生する必要があります。
あなたは、むしろこのようにそれを回避しようとするよりも、あなたのコードで、本当に間違っているものを調査する必要があります。