JavaとC#の両方、そしておそらく他の多くの言語にも、nullパラメータが使用されるべきではない場所で使用された場合にスローされる事前定義の例外クラスがあります。C++で同様のものはありますか?そうでない場合、使用できる別の事前定義の例外はありますか、または独自の例外を定義する必要がありますか?
NULLポインターの逆参照は、C++では未定義の動作です。つまり、コードが機能しているように見えます。例外のスローは保証されていません。あなたは使うことができます
例外(それに意味のある値を提供する-"p is NULL"
)ですが、自分でチェックする必要があります。
通常、C++(またはCの場合)では、neverはNULLポインターを逆参照します。これを行うと未定義の動作(私が知っている実装ではsegfaultのようですが、標準に従って何かが起こる可能性があります)。それはおそらく他の言語でも悪いことですが、私はそれを主張するのに十分なことを知りません。
状況を回復しようとするよりも、状況を回避するのが最善です(とにかくCまたはC++ではできません)。
関連するプログラマーエラーを防ぐための通常のパターンは、次のような関数本体内でassert()
を使用することです。
_int foo(int* myint)
{
// Ensure myint is not NULL
assert(myint);
// Do something with myint
(*myint)++;
return *myint;
}
_
このようなassert()
呼び出しは、リリースビルドでは完全に無視されるため、本番環境では費用はかかりません。彼らは開発を助けるだけです。デバッグビルドで、条件が満たされていない場合、プログラムは非常に明示的なエラーメッセージを表示して直ちに中止します。デバッガーで実行すると、コールスタックを簡単に確認して、正確な理由を調査できます。
C++には、NULLポインターを逆参照するための標準的な例外はありません。
必要な場合は、自分で実装できます。 UNIXでは、SIGSEGVシグナルハンドラーをセットアップし、ハンドラーから例外をスローします。 Windowsでは、_set_se_translator()APIを使用して、「構造化例外」ハンドラーをインストールします。
FTR、C#では、チームメイトに刺されたくない限り、NullReferenceException
sを何も使用しません。 null引数を拒否する代わりにArgumentNullException
があります。 NREは、ユーザーではなく、ランタイムによってスローされることを意図しています。
ただし、これらのいずれかをキャッチするべきではないため、アサーションに対するこれの実際の利点はないことに注意してください。これらがスローされた場合、バグを示しています。これらは、Eric Lippertが 骨抜きの例外 と呼んでいるものであり、それらはあなた自身の重大な障害であり、コードがそれらに対して特に行うべきことは何もありません。
Nullポインターの誤った使用(特に、それを逆参照する)を伴うほとんどすべての場合、C++標準では動作が未定義のままになっています。特定の例外タイプは提供されていません(例外はスローされません)。
ただし、このルールの1つの可能な例外が頭に浮かびます。関数のラップに使用できるC++ 11標準ライブラリテンプレートである_std::function
_には、nullポインターを割り当てることができます。
_std::function<void(int)> func = nullptr;
_
そして、いくつかの引数arg
に対してfunc(arg);
を実行して、その関数でラップされた関数を呼び出そうとすると、_std::bad_function_call
_例外がスローされます。
もちろん、これは他の言語のヌルポインター例外と完全に同等ではありません。
C++でヌルポインターを逆参照すると、未定義の動作が発生し、ほとんどの場合、アプリケーションはセグメンテーションエラーで終了します。 Visual Studioでは、構造化例外処理(SEH)などの拡張機能を使用して、nullポインターの逆参照をキャッチできます。
ポインターへの制限されたインターフェイスを提供するテンプレートクラスでポインターをラップできます。ポインタにアクセスするたびにnullptrチェックを実行し、例外をスローできます。