Java和C#以及可能还有许多其他语言都有一个预定义的异常类,当使用null参数时它会抛出它。 C ++中有类似的东西吗?如果没有,是否有我可以使用的另一个预定义的异常,或者我应该定义自己的异常?
答案 0 :(得分:20)
取消引用NULL指针是C ++中未定义的行为 - 这意味着代码似乎可以正常工作。不保证会抛出异常。
可以使用例外(为其提供有意义的值 - "p is NULL"
),但您必须自己进行检查。
答案 1 :(得分:9)
通常,在C ++(或C语言)中,从不取消引用NULL指针。这样做有未定义的行为(可能是我所知道的任何实现的段错误,但根据标准可能会发生任何事情)。在其他语言中它也可能是一件坏事,但我不知道那些足以断言它。
最好是防止这种情况,而不是尝试从中恢复(无论如何都无法在C或C ++中完成)。
防止一些相关程序员错误的常用模式是在函数体内使用assert()
,例如:
int foo(int* myint)
{
// Ensure myint is not NULL
assert(myint);
// Do something with myint
(*myint)++;
return *myint;
}
此类assert()
调用在发布版本中完全被忽略,因此在生产中没有成本。他们只是帮助发展。在调试版本上,如果不满足条件,程序会立即中止并显示非常明确的错误消息。通过调试器运行它,您可以轻松检查调用堆栈以查询确切原因。
答案 2 :(得分:6)
C ++中没有用于解除引用NULL指针的标准异常。
如果您需要,可以自己实施。在UNIX上设置SIGSEGV信号处理程序并从处理程序中抛出异常。在Windows上,使用_set_se_translator()API安装“结构化异常”处理程序。
答案 3 :(得分:4)
FTR,在C#中你不会使用NullReferenceException
来做任何事情,除非你想被你的队友刺伤。有一个ArgumentNullException
代替拒绝空参数。 NRE应该由运行时引发,而不是你。
但是请注意,这不会对断言产生任何影响,因为你不应该抓住其中一个:如果它们被抛出,它们就表明存在错误。这些是Eric Lippert所称的boneheaded exceptions,它们是你自己的错误,你的代码不应该专门用它们做。
答案 4 :(得分:3)
在几乎所有涉及错误地使用空指针的情况下(特别是,对它进行derefencing),C ++标准只会使行为未定义。没有提供特定的异常类型(并且不会抛出任何异常)。
但是,这个规则有一个可能的例外。 std::function
是一个可用于包装函数的C ++ 11标准库模板,可以为其指定一个空指针:
std::function<void(int)> func = nullptr;
然后,如果您尝试通过func(arg);
对某个参数arg
调用由它包装的函数,它将抛出std::bad_function_call
异常。
当然,这并不完全等同于其他语言的空指针异常,因为它的适用范围要小得多。
答案 5 :(得分:2)
在C ++下解除引用空指针将导致未定义的行为,主要是以分段错误结束应用程序。在Visual Studio下,您可以使用结构化异常处理(SEH)等扩展,以允许捕获空指针解除引用。
答案 6 :(得分:0)
您可以将指针包装在模板类中,该模板类为该指针提供了有限的接口。每当您访问指针时,它都可以执行nullptr检查,并引发异常。