繁体   English   中英

为什么在异常处理c ++中在catch之前需要一个try块

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM