【问题标题】:Is there a way to determine if an exception is occurring?有没有办法确定是否发生异常?
【发布时间】:2010-09-12 17:04:48
【问题描述】:

在析构函数中,有没有办法确定当前是否正在处理异常?

【问题讨论】:

  • 这闻起来很可疑。如果发生异常,为什么要进行不同类型的清理?
  • 同意可疑。而且你永远不想扔出析构函数IMO。但是你可以从析构函数中抛出,但是如果你从析构函数中抛出而另一个异常正在传播,应用程序将终止(不退出或正常清理)

标签: c++ exception exception-handling destructor


【解决方案1】:

您可以使用 std::uncaught_exception(),但它可能不会像您认为的那样做:请参阅 GoTW#47 了解更多信息。

【讨论】:

    【解决方案2】:

    正如 Luc 所说,您可以使用 std::uncaught_exception()。但你为什么想知道?不管怎样,destructors should never throw exceptions!

    【讨论】:

    • 是的,试图通过在已经展开时不抛出来避免最终进入 terminate() 的气味。
    【解决方案3】:

    您可以使用Boost Test Library。看这里的一个小例子:

    struct my_exception1
    {
        explicit    my_exception1( int res_code ) : m_res_code( res_code ) {}
        int         m_res_code;
    };
    
    
    struct my_exception2
    {
        explicit    my_exception2( int res_code ) : m_res_code( res_code ) {}
        int         m_res_code;
    };
    
    class dangerous_call {
    public:
        dangerous_call( int argc ) : m_argc( argc ) {}
        int operator()()
        {
            if( m_argc < 2 )
                throw my_exception1( 23 );
            if( m_argc > 3 )
                throw my_exception2( 45 );
            else if( m_argc > 2 )
                throw "too many args";
    
            return 1;
        }
    
    private:
        int     m_argc;
    };
    
    
    void translate_my_exception1( my_exception1 const& ex )
    {
        std::cout << "Caught my_exception1(" << ex.m_res_code << ")"<< std::endl;
    }
    
    
    void translate_my_exception2( my_exception2 const& ex )
    {
        std::cout << "Caught my_exception2(" << ex.m_res_code << ")"<< std::endl;
    }
    
    
    
    int 
    cpp_main( int argc , char *[] )
    { 
        ::boost::execution_monitor ex_mon;
        ex_mon.register_exception_translator<my_exception1>(
            &translate_my_exception1);
        ex_mon.register_exception_translator<my_exception2>(
            &translate_my_exception2);
        try{
         // ex_mon.detect_memory_leak( true);
          ex_mon.execute( ::boost::unit_test::callback0<int>( 
              dangerous_call( argc ) ) );
        }   
        catch ( boost::execution_exception const& ex ) {
            std::cout << "Caught exception: " << ex.what() << std::endl;
        }
        return 0;
    }
    

    您必须深入研究文档。这是一个非常强大的库来测试你的软件!无论如何,在 Boost 的帮助下,您可以在函数测试的任何地方捕获任何类型的异常!

    【讨论】:

    • 当然你的测试函数可以在你重载 () 操作符的结构体中......你可以在那里进行测试以查看生成了什么异常
    • 建议:如果您使用“代码示例”格式(答案编辑器中的“1”和“0”按钮)进行包装,您的代码示例将更容易阅读。
    猜你喜欢
    • 2018-09-06
    • 2011-08-26
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多