处理程序函数中引发异常
Exception thrown in handler functions
我正在阅读应用C++书中的以下文本。
可以从我们的处理程序函数中抛出异常吗?答案是的,确实可以抛出错误。问题是异常必须出现在可能transversed,直到捕捉到异常。如果不这样做应用程序将调用std::terminate()。对于大型系统相当于向每个函数添加异常规范,除非您完全了解应用程序的动态。它在析构函数中cath所有异常也很重要;否则,在这种情况下还会调用std::terminate()。
在上面的文章中,我有以下问题,需要你们的帮助才能理解。
-
作者所说的"异常必须存在于可能遍历的每个预期规范中"是什么意思?
-
我的理解是,析构函数不能使用异常。author在析构函数中捕获所有异常是什么意思。
要求用简单的例子说明
谢谢你的时间和帮助。
通常,异常规范是个坏主意,因为当你修改规范时,它会产生很多重构和规模问题(autor谈论的问题)。这是java检查异常的情况。C++没有检查异常,但如果您想编写一个统一的API,异常规范的问题是一样的。
事实上,异常规范自C++11以来就已被弃用。C++11使用noexcept
说明符来确保函数不会引发任何异常。这允许某些编译器优化,当然也为函数的用户提供了保证。如果一个函数没有noexcept
说明符,它可以抛出异常,也可以不抛出异常。
正如它的名字所说,例外是例外。也就是说,使用try...catch
进行流量控制是一种糟糕的编程技术。如果你的程序设计得很好,那么当抛出异常时,就意味着出现了非常非常错误的情况。也就是说,这是一个特殊的执行案例。通常,该异常执行事件会转换为执行中止。这就是为什么函数在任何可能引发异常的地方都没有try..catch
块的原因。
当抛出异常而未捕获时,堆栈将展开。这意味着将调用析构函数,所有内容都将被很好地清理。但考虑一下:
foo::~foo()
{
bar();
}
如果由于未捕获的异常而到达foo
的析构函数,而bar();
恰好抛出,则应用程序将立即终止,因为C++不能同时处理多个异常。
如果我们,例如,吞下例外:,这就不会发生
foo::~foo()
{
try { bar(); } catch(...) { /* nom nom */ }
}
更新:
第一部分指的是这样的异常规范:
struct foo
{
void bar() throw();
}
此规范的有效语法为
throw() // does not throw any exception
throw( list of exceptions ) // may throw one of these exceptions
throw(...) // may throw any exception
但正如rodrigo所提到的,这是一个坏主意,因为这些规范导致(在运行时)动态检查是否抛出异常,从而显著降低了性能。
在C++11中,它被noexcept
关键字替换:
noexcept(true)
noexcept(false)
noexcept // identical to noexcept(true)
这是对编译器的保证,而不是相反。
但现在终于轮到你的问题了。当您在某个嵌套链中给定throw
异常规范,并且在深度嵌套的函数中抛出异常时,您将不得不在这一过程中更新每个函数的签名。另一个很好的理由是为什么异常规范是愚蠢的,不应该再使用了。
-
异常规范被证明是个坏主意,我认为它们在该语言的最新版本中已经被弃用,所以我会忽略它
-
一般来说,析构函数不能抛出任何异常。因为它们是在抛出/捕获异常时发生的堆栈展开过程中调用的。如果在堆栈展开时引发异常,程序将中止。简单/安全的解决方案是用
try {...} catch (..} {}
块包裹析构函数体。
- 为什么异常不退出程序?
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 来自 Android 应用程序内部的 boost 类型的 boost::wrapexcept<boost::system::system_error> 的未捕获异常
- 在C++程序中使用的迭代器中未处理的异常
- 与异常处理程序中的操作员<<不匹配
- 捕获异常后如何退出程序执行
- 捕获全部处理程序检测C++中的子类异常
- 数组 C++ 上的异常处理程序
- SDL_Image库会使程序崩溃或使其行为异常
- 从终止处理程序访问所有未捕获的异常
- 引发未经处理的异常:简单 C++ 程序中的读取访问冲突,动态增加数组长度以存储数字
- 使用 C++ dll 运行 c# 应用程序会生成无法加载异常
- 视觉 std::矢量无异常:警告 C4530:使用了C++异常处理程序,但未启用展开语义.指定 /EHsc
- 奇怪的消息 (_Base_bitset::_M_do_to_ulong) 从溢出异常处理程序中打印出来
- 从处理程序捕获时如何获取 Ada 异常消息C++?
- 核心消息传递中未处理的异常.dll在程序关闭期间
- C++ 未捕获异常,程序将终止并中止
- C++程序在第一次尝试时会给出垃圾,但如果它捕获异常并重试,则会给出适当的值
- 如何处理异步函数中的异常UWP应用程序getFileFrompathAsync(path);
- 未处理异常- c++程序在强制转换时停止