[英]Why is there a need for a try block before catch in exception handling c++
是否可以在不使用 try 块的情况下抛出异常并捕获它? 前任:
int main()
{
throw 1;
catch(int){
std::cerr << "caught exception\n";
}
return 0;
}
根据我的经验,你必须结合使用 try 和 catch 块。 如果在 try 块中发生任何错误,则仅将其传递给 catch 块。 因此,如果没有 try 块,那么它将不知道在哪里查找错误。 因此它们需要结合使用。 我不确定在 C++ 中,但在 Java 中,如果将类扩展为 throwable,则可以单独使用 catch 块。
在飞行异常期间,程序控制流的行为略有不同。 try-catch
块有望将程序带回通常的控制流程。
在程序中的任何一点抛出异常时。 正常的程序控制流停止。 程序控制流现在通过运行时的异常处理机制。 这与正常情况不同。 对于正常情况,自动存储的析构函数总是在控制流到达范围(生命周期) “ }
”结束时运行。 对于飞行中的异常,它们比正常运行更早
考虑一下(注意评论);
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)
这发生在整个堆栈展开过程中,并且递归地展开所有函数......直到我们回到调用std::terminate
main()
。
现在,使用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
站点的整个封闭范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.