尽管 C++ 没有强制要求,但常见的做法是从异常对象std::exception或其子类之一派生。
我知道的唯一例外(不是双关语)是boost::thread_interrupted. (std::nested_exception应该用作混合而不是直接抛出)。
此外,catch (...)无法提供有关它捕获的异常的任何信息。
鉴于此,在新代码中catch (...)代替或补充使用的原因(如果有)是什么?catch (std::exception const&)
catch(...)当您想捕获异常以便稍后通过std::current_exception. 例如,如果工作线程中发生错误,您可能希望调度任务的线程而不是工作线程来处理异常。
当您打算立即重新抛出异常,但想在执行之前运行一些代码时,可以使用它。您可以throw;在异常处理程序中的代码之后调用catch(...),以重新抛出完成后捕获的任何异常。
当您不知道函数可能抛出什么异常时(也许您正在使用文档记录不完善的库),可以使用它。它可以让您知道出了什么问题,即使您不知道到底出了什么问题。这是否比终止更好取决于上下文。
它可以用来 100% 确定你捕获到任何东西。例如,如果您正在编写一个使用 C 兼容 API 的库,则必须将异常转换为 C 可以理解的内容,例如错误代码。您可以用作catch(...)最终处理程序来报告一些“未知错误”错误代码并确保函数不会泄漏任何异常。
有很多用例catch(...),无论是因为您想要编写不立即特别关心异常类型的通用代码,还是作为一种解决函数对象类型缺乏约束的方法可以扔。
忽略这是否真的是实际程序中的“常见做法”的问题(Qt 不同意),重点catch(...)是进行不需要与异常本身交互的清理工作。
如今常见的做法是将此类清理逻辑封装到堆栈上的 RAII 对象的析构函数中。当这些事情不容易完成时,catch(...)只要你throw;最后完成,就可以作为一个可行的替代方案。
但catch(...)对于以非本地方式转发异常也很有用。例如,如果您正在编写线程池,如果异常逃脱了任务函数的“main”函数,您需要捕获它并将其转发给等待任务的人员。这是使用catch(...)和完成的current_exception():
try
{
my_task.set_value(std::invoke(task_func, params));
}
catch(...)
{
//Captures the exception and forwards it to the task.
my_task.exception(std::current_exception());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |