如何正确捕获std并增加异常

nix*_*nix 14 c++ logging boost exception-handling

请告诉我如何使用boost :: exception正确使用try/catch.

这是一个例子

void Settings::init(const std::string &filename)
{
    using boost::property_tree::ptree;
    try 
    {
        read_xml(filename, pt);
    }
    catch(boost::exception const&  ex)
    {
        LOG_FATAL("Can't init settings. %s", /* here is the question */);
    }
}
Run Code Online (Sandbox Code Playgroud)

我是否也需要catch std :: exception?我不能让我的应用程序失败,所以我只需要记录所有内容.

UPD: 我现在也无法理解从异常中检索记录的信息???

Fle*_*exo 12

std::exception有一个叫做成员函数what()返回一个const char*可以解释发生了什么.如果你想记录它(猜测以某种方式LOG_FATAL包装printf)你可以做:

catch(std::exception const&  ex)
{
    LOG_FATAL("Can't init settings. %s", ex.what());
}
Run Code Online (Sandbox Code Playgroud)

对于boost::exception虽然你可以使用boost::get_error_info以了解更多关于它.

  • 除非我弄错了,否则boost :: exception不会从std :: exception继承,因此你调用.what()的示例无效.另外,我相信std :: exception通常会返回一个const char*而不是std :: string (5认同)
  • 虽然要从`boost :: exception`访问`what()`,你需要捕获或`dynamic_cast`到`std :: exception`. (2认同)
  • @Qix这些天我没有做足够的C++来调查,但肯定看起来像`booost :: exception`不继承自`std :: exception`:http://www.boost.org/doc/libs/ 1_55_0 /库/异常/ DOC/boost_exception_exception_hpp.html (2认同)

小智 7

可能回答太晚了......但是

        <...snip...>
        catch (const boost::exception& e)
        {
            std::string diag = diagnostic_information(e);
            // display your error message here, then do whatever you need to, e.g.        
            LOG_FATAL("Can't init settings. %s", diag);
        }
        <...snip...>
Run Code Online (Sandbox Code Playgroud)


Ker*_* SB 5

与任何C++一样,以下通用规则适用:

捕获可能抛出的所有异常,并且只有您可以有意义地响应它们时.

你也可以捕获所有其他异常(...)并创建一个日志消息或类似的东西,但是你必须重新抛出它们(throw;).如果除了中止某些操作之外,您在代码中无能为力,那么您不需要处理异常.让它冒泡到一个可以有意义地使用它的地方.

在你的代码中,你必须至少允许内存分配错误(std::bad_alloc),所以你可以检查那些,如果这是有道理的.但是,如果你不知道自己捕获的是什么,那么你所捕获的东西并不多.

说你的"程序不能失败"只能意味着这么多.最后,如果你有一个顶级数据结构的分配错误,没有什么你可以做的.我能想象的最佳场景是你的main函数是否在循环中处理一些数据; 在这种情况下,您可以在循环周围放置一个通用try块,如果出现异常,您只需转到下一轮.但我认为这是一个能够"有意义地处理异常"的例子,所以这只是上述的一个特例.一般情况下,虽然您可能希望将整个main函数包装在try块中,但您必须接受在最终的catch-all情况下,您没有太多选择,只能中止该程序.