受嵌套处理程序影响的异常的生命周期
Is the lifetime of an exception affected by nested handlers?
考虑以下代码片段:
struct ExceptionBase : virtual std::exception{};
struct SomeSpecificError : virtual ExceptionBase{};
struct SomeOtherError : virtual ExceptionBase{};
void MightThrow();
void HandleException();
void ReportError();
int main()
{
try
{
MightThrow();
}
catch( ... )
{
HandleException();
}
}
void MightThrow()
{
throw SomeSpecificError();
}
void HandleException()
{
try
{
throw;
}
catch( ExceptionBase const & )
{
// common error processing
}
try
{
throw;
}
catch( SomeSpecificError const & )
{
// specific error processing
}
catch( SomeOtherError const & )
{
// other error processing
}
ReportError();
}
void ReportError()
{
}
标准第15.1.4节告诉我们:
所抛出异常的临时副本的内存为以未指定的方式分配,除非在3.7.3.1中指出。的只要有正在执行的处理程序,临时就会持续存在这个例外。特别地,如果处理程序通过执行扔;语句,该语句将该控件的控制传递给另一个处理程序异常,因此临时保留。最后一个处理程序以除throw以外的任何方式执行异常退出;的临时对象被销毁,并且实现可以释放临时对象的内存;任何这样的重新分配都是在一种未指明的方式。破坏立即发生在类的异常声明中声明的对象的销毁处理程序。
我将main
中的处理程序视为"最后一个处理程序"是否正确?因此,在HandleException
中允许任何数量的重新抛出和捕获,而不会导致当前异常对象的破坏?
我是否正确地将main中的处理程序视为"最后一个处理程序" ?
是的,你是。
因此在HandleException中允许任意数量的重新抛出和捕获而不会导致当前异常对象的破坏?
是的。最后未处理的异常对象将被编译器生成的代码销毁。没有内存泄漏。
在HandleException()
中重新投掷是不好的。而不是1. 将捕获写入请求特定处理的任何异常类型;2. 您可以使用dynamic_cast
对异常处理进行分组。捕获基异常类型并尝试将其向下强制转换为其任何派生异常类。但是dynamic_cast
不是一个好的练习。因此,最好使用第一种解决方案。
最好这样重写你的代码:
struct ExceptionBase : virtual std::exception{};
struct SomeSpecificError : virtual ExceptionBase{};
struct SomeOtherError : virtual ExceptionBase{};
void MightThrow();
void HandleExceptionBase();
int main()
{
try
{
MightThrow();
}
catch (SomeOtherError &error) {
// first common code
HandleExceptionBase();
// react on this exception correctly
// specific code
}
catch (SomeSpecificError &error) {
// first common code
HandleExceptionBase();
// react on this exception correctly
// specific code
}
catch (ExceptionBase &error) {
HandleExceptionBase();
// finally catch anything derived from base class
// react on this exception correctly
}
catch(...) {
// react on any other exception except 3 listed above
}
}
void MightThrow()
{
throw SomeSpecificError();
}
void HandleExceptionBase() {
// base exception handler
}
感谢到目前为止张贴的评论和回答。我还没有看到我想要的东西,所以我将从aschpler提供的答案中添加一些信息到我的后续问题中。
我认为这里的标准语言非常清楚,15.3p7:当catch子句. ...的形式参数(如果有的话)初始化完成时,处理程序被认为是活动的一个处理程序当catch子句退出或Std::unexpected()在抛出后退出。
15.3p8:最近激活的处理程序仍然处于活动状态的异常称为当前处理的异常。
main
实际上是最后一个处理程序。因此,异常的生命周期不受嵌套处理程序的影响。
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何将strftime中的格式错误作为异常捕获
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 尝试使用智能指针时引发异常
- 函数如何通知用户它基于函数原型抛出异常?
- C++中抛出异常的生命周期
- 受其他异常影响的异常的生命周期
- 受嵌套处理程序影响的异常的生命周期