如何避免在C ++中使用异常?

时间:2009-09-21 07:26:39

标签: c++ exception

我可以使用哪些技术来避免C ++中的异常,如Google's style guide中所述?

6 个答案:

答案 0 :(得分:8)

  1. 不要抛出异常。
  2. 不要使用STL(严重依赖异常)。
  3. 仅使用new(std::nothrow)或覆盖::operator new以在失败时返回0。
  4. 请注意,通过避免异常,您实际上会丢弃许多有用的库,包括Boost。基本上,你必须从头开始编程。

答案 1 :(得分:3)

不在您自己的代码中抛出异常相对容易:您只是不使用throw语句。

不抛出内存分配失败的异常会更加痛苦:要么你不使用普通new(使用new(std::nothrow)malloc或者其他东西),要么使用一些非标准编译器选项,使其在失败时执行非标准操作(例如,立即终止程序,或返回0),或者在失败时覆盖operator new以执行非标准的操作。

如果您选择的方法是立即终止该程序,您可以使用set_new_handler()来实现这一点,我忘记了这一点,直到litb提醒我。

这就留下了处理由你不维护的C ++库生成的异常的问题。通常,您必须在一个看起来像这样的包装器中包装库调用:

int DoSomething(int &output, const int input) throw() {
  try {
    output = library_do_something(input);
    return 1;
  } catch (...) {
    return 0;
  }
}

catch (...)捕获来自library_do_something的所有可能的C ++异常(以及output上的赋值运算符,这里不相关),抛弃了他们可能拥有的所有信息包含,然后将所有这些失败映射到0

请注意,这种风格意味着你根本不能使用RAII,甚至不能使用RAII,因为你无法在构造函数中发出信号失败的信号。 RAII的重点在于您获取构造函数内的所有资源,以便在异常传播期间由析构函数正确释放它们。但资源获取本质上总是会失败。所以你不能在构造函数中做到这一点。

答案 2 :(得分:2)

我很想知道为什么人们会想要避免C ++中的异常以及用什么机制代替它们来处理意外失败的现实,同时仍保持体面的结构。

确保将它们添加到不使用RAII类型语义的现有代码库中是非常昂贵的 - 但如果正在进行绿色领域开发,那么您会建议什么样的替代方案以及如何证明不使用高质量库使用异常与编写自己的异常免费/无bug替代方案?

答案 3 :(得分:1)

样式指南说他们“不使用例外”就是这样 - 他们不会抛出它们而不会调用任何可能抛出它们的东西(例如,他们会使用new(std::nothrow)而不是通常new,因为后者在无法分配内存时会抛出bad_alloc

答案 4 :(得分:0)

在某些编译器中,您可以关闭异常处理。这可能会导致外部代码出现意外结果 - 这不是我想要尝试的。

除此之外,显而易见的第一步是避免从您自己的代码中抛出异常,可能是通过自由使用nothrow directive,并尝试通过{{避免从外部(第三方)代码中抛出异常3}}

这意味着您的代码需要始终了解可能的外部异常故障情况,例如内存不足,磁盘空间不足,互联网连接丢失,硬件故障以及任何其他情况。可能导致代码抛出......

在某些情况下,您可以使用某些代码的无异常版本(例如throw-new与非抛出新代码)。

答案 5 :(得分:0)

我要做的是永远不要在自己的代码中引发异常,并“翻译”或包装执行此操作的任何外部代码。