int compare(int a, int b) {
if (a < 0 || b < 0) {
throw std::invalid_argument("a or b negative");
}
}
void foo() {
try {
compare(-1, 0);
} catch (const std::invalid_argument& e) {
// ...
}
}
它在StackOverflow here和here中进行了描述,如何在代码中使用 get a backtrace on your exceptions 而无需调试器或繁琐的日志记录,只需编写一个适当的异常处理程序即可重新抛出嵌套异常 .
由于您可以对任何派生的异常类执行此操作,因此可以向此类回溯添加大量信息!你也可以看一下我的MWE on GitHub,其中一个回溯看起来像这样:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
5 回答
简单:
标准库附带了一个很好的built-in exception objects集合,你可以抛出 . 请记住,您应该始终按值引用并通过引用捕获:
每次尝试后都可以有多个catch()语句,因此如果需要,可以单独处理不同的异常类型 .
您还可以重新抛出异常:
并且无论类型如何都要捕获异常:
只需在需要的地方添加
throw
,并将try
块添加到处理错误的调用者 . 按照惯例,你应该只抛出从std::exception
派生的东西,所以首先包括<stdexcept>
.另外,请查看Boost.Exception .
虽然这个问题相当陈旧并且已经得到了解答,但我只想补充说明如何在C 11中进行适当的异常处理:
使用std :: nested_exception和std :: throw_with_nested
它在StackOverflow here和here中进行了描述,如何在代码中使用 get a backtrace on your exceptions 而无需调试器或繁琐的日志记录,只需编写一个适当的异常处理程序即可重新抛出嵌套异常 .
由于您可以对任何派生的异常类执行此操作,因此可以向此类回溯添加大量信息!你也可以看一下我的MWE on GitHub,其中一个回溯看起来像这样:
您可以定义在发生特定错误时要抛出的消息:
或者你可以像这样定义它:
通常,你会有一个像这样的
try ... catch
块:在自定义异常的情况下,希望 ADD 到此处描述的其他答案附加说明 .
如果您创建自己的自定义异常,该派生自
std::exception
,当您捕获"all possible"异常类型时,应始终使用可能被捕获的"most derived"异常类型启动catch
子句 . 查看示例(要做什么 NOT ):NOTE:
0)正确的顺序应该反过来,即 - 首先你
catch (const MyException& e)
,然后是catch (const std::exception& e)
.1)正如您所看到的,当您按原样运行程序时,将执行第一个catch子句(这可能是您首先想要做的事情) .
2)即使第一个catch子句中捕获的类型是
std::exception
类型,what()
的"proper"版本也将被调用 - 因为它被引用捕获(至少将捕获的参数std::exception
类型更改为值 - 您将体验到行动中的"object slicing"现象) .3)如果“由于XXX异常被抛出的事实导致的某些代码......”对异常类型做了重要的事情,那么这里的代码存在不当行为 .
4)如果捕获的对象是"normal"对象,这也是相关的:
class Base{};
和class Derived : public Base {}
...5)
g++ 7.3.0
在Ubuntu 18.04.1上产生一个警告,表明上述问题:Again ,我会说,这个答案只是对这里描述的其他答案的答案(我认为这一点值得一提,但却无法在评论中描述) .