10

私は完全に壊れているように見えるこのコードに出くわしましたが、それは実際に起こりthisますnull。これがどうなるかわからないnull

これは、次のような通常のメソッド呼び出しの内部にあります。

myObject->func();

MyObject::func()には

if (!this) { return false; }

(?)メソッドNullPointerExceptionの中に入る代わりに最初の行をスローする方法はありますか?null

4

7 に答える 7

22

あなたが持っている場合:

MyObject *o = NULL;

o->func();

次に何が起こるかfuncは、仮想かどうかによって異なります。そうである場合、vtable を取得するオブジェクトが必要なため、クラッシュします。ただし、仮想でない場合、呼び出しは this ポインターを NULL に設定して続行します。

標準ではこれは「未定義の動作」であると述べているため、何かが起こる可能性がありますが、通常のコンパイラは、ポインターが NULL かどうかをチェックしないようにコードを生成するだけです。いくつかのよく知られているライブラリは、私が説明した動作に依存しています。MFC にはSafeGetHandle、null ポインターで呼び出すことができるような関数があり、その場合は NULL を返します。

再利用可能なヘルパー関数を書きたいと思うかもしれません:

void CheckNotNull(void *p)
{
    if (p == NULL)
        throw NullPointerException();
}

次に、関数の開始時にそれを使用して、以下を含むすべての引数をチェックできますthis

CheckNotNull(this);
于 2009-03-19T18:04:13.110 に答える
2

shared_ptrこれらの種類のエラーを (設計により) トラップする方法は、null ポインター引数を使用して作成時にスローするポインター ラッパー クラス (に似ている) を使用することです。逆参照されたときにもスローされる可能性がありますが、それは少し遅いです-何もないよりはましだと思います。

于 2009-03-19T18:12:12.480 に答える
1
if(this == null)
   throw new NullPointerException;
if(!this)
   return false;
于 2009-03-19T18:03:18.133 に答える
1

thisnull になる可能性があります。このコードは、オブジェクトの初期化がまだ完了していない、または削除された競合状態を (ひどく) 検出しようとしていると思われます。

于 2009-03-19T18:06:44.913 に答える
1

(this == NULL) は、標準によれば未定義の動作です。このチェックを削除する必要があると思います:)

次の呼び出しを行うとします。

((CSomeClass*) 0)->method();

動作はすでに定義されていないので、わざわざ CSomeClass::method で == NULL のチェックを行う必要はありません。

編集済み: メンバー変数を使用しない場合、コンパイラは (0 == this) を処理すると仮定しますが、仮想テーブル ポインタはどこにあるのでしょうか? この場合、あなたのクラスはポリモーフィズムを使用できません。

于 2009-03-19T18:07:51.680 に答える
0

このポインターは、次のような場合に 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();
}

アクセス違反の例外を回避するために、誰かが簡単なハックをしたと思います。

于 2009-03-19T18:06:10.357 に答える
-1

this == null は、削除されたオブジェクトでメソッドを呼び出している場合、または何かがメモリに書き込まれてはならない (特にオブジェクトの this ポインターを上書きしている) 場合にのみ発生します。

このように回避しようとするのではなく、コードの実際の問題を調査する必要があります。

于 2009-03-19T18:04:18.927 に答える