为什么在这段代码中有核心转储我看到了输出
Catch
terminate called after throwing an instance of 'std::runtime_error'
what(): ZERO DIV
Aborted (core dumped)
但我希望
Catch
terminate called after throwing an instance of 'std::runtime_error'
what(): ZERO DIV
我的密码
class Q {
public:
Q(int a, int b) try
: val(b != 0 ? a / b : throw runtime_error("ZERO DIV"))
{
cout << "Q()" << endl;
}
catch(...)
{
cout << "Catch " << endl;
val = nullopt;
}
~Q() {
cout << "~Q()" << endl;
}
private:
optional<int> val;
};
int main() {
Q q = {1, 0};
return 0;
}
我认为核心转储的原因是a / B的执行,但我不应该被执行,因为b不为零
1条答案
按热度按时间xxhby3vn1#
如果构造函数的function-try-block中的异常处理程序没有通过异常退出,则当前处理的异常会自动重新抛出。
这是必要的,因为如果构造函数抛出了异常,那么程序就不可能在
Q q = {1, 0};
之后正常地继续,因为对象q
不能被正确地构造和使用。您看到核心转储是因为您没有在
main
中的任何地方处理重新引发的异常,导致调用std::terminate
,调用std::abort
,然后发出信号SIGABRT
,SIGABRT
没有在任何地方处理,因此操作系统生成核心转储(如果配置为这样做)。此外,在构造函数的异常处理程序中访问
val
将导致未定义的行为。val
的生存期尚未开始,因为它从未初始化。如果你仍然希望构造成功,你就不能使用函数try块,完全避免使用异常,如果你必须使用异常,在普通的try-catch块中处理异常。