29

Java 和 C#,可能还有许多其他语言,都有一个预定义的异常类,当在不应该使用 null 参数时抛出该异常类。C ++中有类似的东西吗?如果没有,我是否可以使用另一个预定义的异常,或者我应该定义自己的异常?

4

7 回答 7

27

取消引用 NULL 指针在 C++ 中是未定义的行为——这意味着代码看起来可以工作。不保证会抛出异常。您可以使用

std::invalid_argument

异常(为其提供有意义的值 - "p is NULL"),但您必须自己进行检查。

于 2013-01-03T12:51:30.107 回答
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()调用在发布版本中完全被忽略,因此在生产中没有成本。他们只是帮助发展。在调试构建时,如果不满足条件,程序会立即中止并显示非常明确的错误消息。通过调试器运行它,您可以轻松检查调用堆栈以调查确切原因。

于 2013-01-03T12:47:58.193 回答
6

C++ 中没有用于取消引用 NULL 指针的标准例外。

如果你想要它,你可以自己实现它。在 UNIX 上设置 SIGSEGV 信号处理程序并从处理程序中抛出异常。在 Windows 上,使用 _set_se_translator() API 安装“结构化异常”处理程序。

于 2013-01-03T14:15:12.867 回答
4

NullReferenceExceptionFTR,在 C# 中,除非您想被队友刺伤,否则您不会将s 用于任何事情。有一个ArgumentNullException用于拒绝空参数的替代方法。NRE 是由运行时抛出的,而不是你。

但请注意,与断言相比,这并没有真正的优势,因为您不应该捕获其中之一:如果它们被抛出,则表明它们存在错误。这些是 Eric Lippert 所说的愚蠢的异常,它们是你自己的错误,你的代码不应该专门对它们做任何事情。

于 2013-01-03T12:50:15.847 回答
4

在几乎所有涉及错误使用空指针(尤其是取消引用它)的情况下,C++ 标准只是简单地保留了未定义的行为。没有提供特定的异常类型(也不会抛出异常)。

不过,我想到了这个规则的一个可能的例外。std::function,这是一个可用于包装函数的 C++11 标准库模板,可以分配一个空指针:

std::function<void(int)> func = nullptr;

然后,如果您尝试通过执行func(arg);for some argument来调用由它包裹的函数arg,它将引发std::bad_function_call异常。

当然,这并不完全等同于其他语言的空指针异常,因为它的普遍适用性要差得多。

于 2013-01-03T12:57:14.363 回答
2

在 C++ 下,取消引用空指针将导致未定义的行为,这主要以分段错误结束应用程序。在 Visual Studio 下,您可以使用结构化异常处理 (SEH) 等扩展,这些扩展允许捕获空指针取消引用。

于 2013-01-03T12:54:02.500 回答
0

您可以将指针包装在模板类中,该类为指针提供有限的接口。每当您访问指针并抛出异常时,它都可以进行 nullptr 检查。

于 2019-08-12T18:50:06.050 回答