abi*_*bir 7 c++ exception-handling exception try-catch c++11
我对异常处理的理解非常有限.虽然我发现很容易抛出异常(或者我可以将它打包expected<T>用于以后的消费),但我对如何处理异常几乎一无所知.
目前我的知识仅限于
清理我自己的资源并重新抛出要在适当位置处理的异常.例如
ptr p = alloc.allocate(n);
try
{
uninitialized_copy(first,last,p);//atomic granularity, all or none
}
catch(...)
{
alloc.deallocate(p,n);
throw;
}
Run Code Online (Sandbox Code Playgroud)但我想,这可以在一个RAII模式中等效地转换为
alloc_guard<ptr> p{alloc.allocate(n)};
uninitialized_copy(first,last,p.get());
p.commit();
Run Code Online (Sandbox Code Playgroud)
在顶层捕获异常,撰写并打印一条好消息并退出.eg
int main(int argc,char** argv)
{
try
{
app_t the_app(argc,argv);
the_app.run();
}
catch(std::runtime_error& e)
{
//instead of what, I can also compose the mesage here based on locale.
std::cout<<e.what()<<std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)所以,我所做的就是处于顶级功能,例如main捕获异常并打印相应的消息并关闭.
在使用各种外部库作为实现的后端实现具有一组良好API的库时,我意识到第三方库异常是我的API规范的一部分,因为它们跨越我的库边界并落在用户代码中!
因此,我的库API泄露了我用于用户代码的外部库(并且每个库都有自己的异常层次结构)的所有异常.
这导致了我的问题,当我发现任何异常时可以做些什么?
进一步来说,
mpl::map)吗?file_not_found或者disk_error,用另一个文件重新运行该函数)?谢谢
这是一个非常大的话题。
我怀疑您是否可以轻松地将第三方异常转换为您自己的异常,而且我个人认为没有必要实现这种行为。由于第 3 方库是您的实现的一部分,它没有公开给公共 API,为什么您要公开它的所有异常(即使通过一些映射)?如果有一天您坚持使用另一个实现相同内容的第三方库 - 您愿意重新设计整个异常层次结构吗?我想不是。你的库的 API 一定不能脆弱,所以我建议不要将外部异常映射到你自己的异常。
您可以通过以下方式将第 3 方例外映射到您的层次结构:
根本不要包裹任何东西。我的意思是你不必仅仅因为第三个图书馆这样做就扔掉任何东西。您可以捕获该异常并处理它,或者返回错误代码,或者适当地更改状态。除了总是重新抛出之外,还有许多其他可能性。
您不必对所有第 3 方例外情况进行一对一翻译。如果您在内部使用库 AAA,那么您可以使用单个 AAAException 来表示来自该库的许多异常。
值得了解的是:始终通过 const 引用捕获异常:
catch (const exception & ex)
这个话题很大,希望我的回答有助于理解。
对评论的答复:
如果我不将第三方异常映射到我自己的 API(不需要一对一),它们就会泄漏到客户端代码- 不,他们不会,这就是重点!您必须在库中捕获它们,然后决定如何处理捕获的异常:抛出您自己的异常、返回错误代码、通知客户端侦听器、记录错误等...
try {
3rdpatry.call();
} catch (const 3rdpartyException & ex) {
// throw YourException(ex.what());
// listener.notify(some_error)
// return some_code
}
Run Code Online (Sandbox Code Playgroud)通过 const 引用捕获根本不是为了防止切片。这里有一个很好的讨论解释了这一点。