c++ - 关于异常规范和应用程序设计的问题

标签 c++ design-patterns exception try-catch

虽然这个话题已经在 SO 上进行了广泛的讨论,但考虑到以下事实,我想澄清一些我仍然不清楚的事情:

  1. 10 年前,Herb Sutter 告诉我们 refrain from using this functionality .

  2. 指定函数/方法可能抛出的异常不会迫使编译器在您决定更改函数体并抛出新类型的异常时对您大喊大叫,而忘记更改异常规范在函数的声明中。

  3. 如果您有一个非常高级的函数,它调用其他几个高级函数,每个函数都运行大量代码来生成结果,那么我可以想象当我必须指定 ALL 时,维护会是 hell 般的噩梦第一个函数可能抛出的错误,并且这个列表必须包括内部函数可能抛出的所有异常等等,从而在高级函数和低级函数之间创建紧密耦合,这是非常不希望的。另一方面,我们从 std::runtime_error 派生所有异常,其中 we know is a good practice我们可以指定高级函数只抛出 std::runtime_error 并完成它。但是等一下......我们实际上在哪里捕获异常?当高级函数应该只抛出 std::runtime_error 时,将对这些高级函数之一的调用包含在 try/catch block 中(捕获 MyVerySpecific 异常)不是很奇怪/令人讨厌/不好吗? ?在较低级别的函数中捕获特定的异常是否有好处,这些函数无法对它们执行任何操作,而是将它们传递到更通用的容器中,并附加更多信息?我当然不想在我编写的每个函数中都编写 try/catch block ,只是为了格式化异常。这就像要求每个函数都验证其参数一样,当人们需要更改低级函数中的某些内容时,这可能会让人们发疯。

问题:

  1. Herb Sutter 关于异常规范的咆哮至今仍然有效吗?从那以后有什么改变吗?我最感兴趣的是 C++0x 之前的标准。如果是的话,我想我们可以考虑结束这个话题了。

  2. 由于编译器似乎大多会忽略这些异常规范,而在捕获异常时,99%的情况下都会使用catch (const CustomException &ex),那么如何指定函数抛出 CustomException? 抛出(CustomException)抛出(CustomException &)抛出(const CustomException &)?我已经看到了所有的变化,虽然我会选择第一个,但其他的有任何意义/增加任何好处吗?

  3. 如何实际使用此功能,同时避免上述第三个事实中说明的谬误?

  4. 编辑:假设我们正在构建一个库。如果我们不使用异常规范,用户如何知道会发生什么异常?他们肯定不会看到 API 方法将在内部调用哪些函数...

最佳答案

1/ Do Herb Sutter's rants about exception specification still hold today? Has anything changed since then? I am mostly interested in pre-C++0x standards. If yes, I guess we can consider this topic closed.

是的,它们仍然有效。

异常规范是:

  • 半途实现(例如,函数指针不指定异常)
  • 编译时未检查,但会导致运行时终止!!

一般来说,我会反对异常规范,因为它会导致实现细节的泄漏。查看Java异常的状态...

特别是在 C++ 中?异常规范就像搬起石头砸自己的脚,因为文档中最微小的错误都可能导致 std::terminate 调用。请注意,几乎所有函数都可能抛出 std::bad_allocstd::out_of_range 例如。

注意:自 C++11 起,throw() 已被弃用,现在 C++17 中它已消失;相反,从 C++17 开始,可以使用 noexcept(false) 说明符。它在函数指针中得到了更好的支持,但仍然会导致运行时终止而不是编译时错误。


2/ Since it seems that the compiler mostly ignores these exception specifications, and when catching exceptions, in 99% of the cases, one would use catch (const CustomException &ex), how would one specify that a function throws CustomException? throw(CustomExecption) or throw (CustomException &) or throw (const CustomException &)? I have seen all variations, and, although I would go for the first one, do the others make any sense / add any benefits?

编译器不会忽略异常规范,它会设置非常警惕的看门狗(哪些轴)以确保在您错过某些内容时杀死您的程序。


3/ How would one actually use this functionality, and, at the same time, avoid the fallacies illustrated in the above 3rd fact?

如果保持非正式,您的客户会很感激,所以最好的例子是:

void func(); // throw CustomException

这可以让您专注于同样重要的异常,并让“不重要”的异常溜走。如果消费者想要全部? catch(std::exception const& e) 有效。


4/ EDIT: Suppose that we're building a library. How will its users know what exceptions to expect, if we don't use exception specification? They will certainly not see what functions will be called internally by the API methods...

他们必须这样做吗?

记录重要的事情,std::Exception... 处理意外情况。

关于c++ - 关于异常规范和应用程序设计的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11051540/

相关文章:

c++ - 获取 recv 函数的缓冲区长度

c++ - mac osx 10.7 中的 g++

.net - 引发NullReferenceException时检测目标对象是什么

java - Joda DateTime 非法值

c++ - 退出 Qt 应用程序后如何做

c++ - 使用 std::bind 占位符和 boost 库的问题

javascript - 在 Html5 Canvas 中更改图案大小

c# - 在可以修改的类上使用扩展方法是否可以接受

java - Spring框架的意义

c# - 如何从具有通用返回类型的方法引发异常