是否可以抛出异常并在不使用try块的情况下捕获它? 例如:
int main()
{
throw 1;
catch(int){
std::cerr << "caught exception\n";
}
return 0;
}
答案 0 :(得分:0)
根据我的经验,你必须在组合中使用try和catch块。这里如果try块中发生任何错误,那么只将它传递给catch块。因此,如果没有try块,那么它将不知道在哪里寻找错误。因此,它们需要组合使用。我不确定在C ++中,但在Java中,如果将类扩展为throwable,则可以单独使用catch块。
答案 1 :(得分:-2)
在飞行中的异常期间,程序控制流程的行为略有不同。 try-catch
阻止希望将程序恢复到通常的控制流程。
当程序中的任何一点抛出异常时。 正常程序控制流停止。程序控制流现在通过运行时的异常处理机制。这与 normal 不同。对于普通,自动存储的析构函数始终在控制流到达范围(生命周期) “}
”的末尾时运行。对于飞行中的例外,它们早于正常运行
考虑一下(注意评论);
MyClass foo(){
{
MyClass c;
c.call(balhhh); //assuming this throws
// (1)
....
return c;
}
void bar(){
std::map<K,V> mp;
auto c = foo();
// (2)
mp.insert(c);
....
}
当您致电bar
时,我们可以看到控制流是如何在foo()
处完全离开// (1)
,在// (1)
之后的任何其他代码都不会在foo()
范围内执行foo()
,当// (2)
被解除时,同样的事情就发生了,我们现在在main()
这在整个堆栈展开过程中都会发生,并且这会递归展开所有函数......直到我们回到调用std::terminate
的{{1}}。
现在,使用 try-catch 块,编译器生成的代码在程序移动到catch块后暂停早期退出行为(搜索匹配)处理程序),如果处理异常,控制流程将恢复正常。
考虑:
MyClass foo()
try {
MyClass c;
c.call(balhhh); //assuming this throws
// (1)
....
return c;
}
catch(...){
...
}
void bar(){
std::map<K,V> mp;
auto c = foo();
// (2)
mp.insert(c);
....
}
现在,当异常离开时,控制流离开// (1)
的范数以搜索关联的catch
中的处理程序,如果处理了异常,程序将返回正常的控制流程。 // (2)
之后的代码现在将执行...
从解释中可以看出, try-catch 块是C ++标准规定的唯一方法,用于在抛出异常后恢复正常程序控制流
int main()
{
throw 1; //fine, program control leaves the whole of main at this point.
catch(int){ //illegal, like using an else block without an if
std::cerr << "caught exception\n";
}
return 0;
}
即使上述代码合法,throw
表示控件会将整个封闭范围留在throw
网站。