在析构函数中捕获异常 [英] Catching exceptions in destructors

查看:496
本文介绍了在析构函数中捕获异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有可能做一个析构函数捕获异常,然后重新抛出它们吗?

如果是这样,我该怎么做,因为没有一个明确的地方为尝试语句。

Is it possible to make a destructor catch exceptions and then re-throw them?
If so, how would I do that, since there isn't a clear place for a try statement.

基本上,我想要完成:

CMyObject::~CMyObject()  
{
    catch(...)    // Catch without a try.  Possible?
    {
        LogSomeInfo();
        throw;  // re-throw the same exception
    }
    // Normal Destructor operations
}


b $ b

背景

我有一个大型,复杂的应用程序,在某处抛出未处理的异常。
我不能方便地访问 main 或顶级消息泵或类似的东西,所以没有容易捕捉所有未处理的异常。

Background
I have a large, complex application that is throwing an unhandled exception somewhere. I don't have easy access to main or the top level message-pump or anything similar, so there's no easy place to catch all unhandled exceptions.

我认为任何未处理的异常必须通过一堆析构函数,因为堆栈是解开的。所以,我正在考虑在析构函数中散布一堆 catch 语句。然后至少我知道当异常被抛出时,什么对象在玩。但是我不知道这是可能的还是可取的。

I figure any unhandled exception has to pass through a bunch of destructors as the stack is unwound. So, I'm contemplating scattering a bunch of catch statements in destructors. Then at least I'd know what objects are in play when the exception is thrown. But I have no idea if this is possible, or advisable.

推荐答案

您可以使用 std :: uncaught_expeption 以检查当前是否抛出异常。如果是,您可以尝试从当前异常中提取信息:

You can use std::uncaught_expeption to check if an exception is currently being thrown. If so, you can try to extract information from the current exception:

if( std::uncaught_exception() ) {
    if( const std::exception_ptr eptr = std::current_exception() ) {
        try {
            std::rethrow_exception( eptr );
        }
        catch( const std::exception& e ) {
            std::cerr << "Exception: " << e.what() << std::endl;
            throw;
        }
        catch( ... ) {
            std::cerr << "Unknown exception" << std::endl;
            throw;
        }
    }
    else {
        std::cerr << "Weird, this should not happen!" << std::endl;
    }
}

或者只是做一些清理处理,像你自己不关心异常本身,你只是添加日志取决于析构函数是否由于异常释放堆栈时调用。

or just do some cleanup processing and continue as it looks like you don't really care about the exception itself, you just add the logging depending of whether or not the destructor is called while unwinding the stack due to an exception.

另一个选项可能是 std :: set_terminate 。这是非常有用的,如果你想有一个方法被调用当异常没有被捕获和即将终止程序。在终止处理程序中,我通常在最终终止程序之前打印一些关于异常的信息和一个(demangled)backtrace,它来自于我的日志文件。这是编译器和系统特定的,但是一个真正的帮助器,因为它可以节省大量的时间,如果你写服务器进程,并且往往日志文件是所有你从ops。

Another option might be std::set_terminate. This is useful if you want to have a method called when an exception is not caught and about to terminate the program. In the terminate handler, I usually print some information about the exception and a (demangled) backtrace of where it originates from to my log file before finally terminating the program. This is compiler and system specific, but a real helper as it saves a lot of time if you write server processes and often the log file is all you get from ops.

这篇关于在析构函数中捕获异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆