简体   繁体   English

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

[英]Why is there a need for a try block before catch in exception handling c++

Is it possible to throw an exception and catch it without using a try block ?是否可以在不使用 try 块的情况下抛出异常并捕获它? ex:前任:

int main()
{
    throw 1;
    catch(int){
       std::cerr << "caught exception\n";
    }
    return 0;
}

According to my experience, you have to use try and catch block in a combination.根据我的经验,你必须结合使用 try 和 catch 块。 Here if any error occur in the try block then only it is passed to the catch block.如果在 try 块中发生任何错误,则仅将其传递给 catch 块。 Thus if there is no try block then it won't know where to look for the error.因此,如果没有 try 块,那么它将不知道在哪里查找错误。 Thus they need to be used in combination.因此它们需要结合使用。 I am not sure in C++ but in Java you can use catch block in singly if you extend the class to throwable.我不确定在 C++ 中,但在 Java 中,如果将类扩展为 throwable,则可以单独使用 catch 块。

There is a slight difference in the behavior of program control flow during an exception in flight.在飞行异常期间,程序控制流的行为略有不同。 try-catch blocks hopefully brings the program back to the usual control flow. try-catch块有望将程序带回通常的控制流程。

When an exception is thrown at any point in the program.在程序中的任何一点抛出异常时。 Normal program control flow halts.正常的程序控制流停止。 The program control flow now goes through the runtime's mechanism for exception handling.程序控制流现在通过运行时的异常处理机制。 This is different from what is normal .这与正常情况不同。 For the normal , destructors for automatic storage always runs when control flow reaches the end of scope (lifetime) " } " .对于正常情况,自动存储的析构函数总是在控制流到达范围(生命周期) }结束时运行。 For exceptions in flight, they run earlier than normal对于飞行中的异常,它们比正常运行更早

Consider this (note the comments);考虑一下(注意评论);

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);
     ....
}

When you call bar , we can see how control flow is per-maturely leaves foo() at // (1) , no other code after // (1) is executed within the scope of foo() , the same thing happens when foo() has been unwound, and we are now at // (2)当你打电话bar ,我们可以看到控制流程是如何的每叶成熟foo()// (1)没有其他的代码之后// (1)的范围内执行foo()同样的事情发生时, foo()已经解开,我们现在在// (2)

This happens throughout stack-unwinding process, And this recursively unwinds all functions... until we are back to main() where std::terminate is called.这发生在整个堆栈展开过程中,并且递归地展开所有函数......直到我们回到调用std::terminate main()


Now, with a try-catch block, the compiler generates code that suspends that early exit behavior after program has moved to a catch block (in search for a matching handler), and if the exception is handled, control flow goes back to normal.现在,使用try-catch块,编译器生成代码,在程序移动到 catch 块(寻找匹配的处理程序)后挂起早期退出行为,如果处理异常,控制流将恢复正常。

Consider:考虑:

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);
     ....
}

Now, when the exception leaves, control flow leaves the norm at // (1) to search for the handler in the associated catch , if the exception was handled, the program goes back to the normal control flow.现在,当异常离开时,控制流离开// (1)处的规范以在关联的catch搜索处理程序,如果异常被处理,程序将返回正常控制流。 Code after // (2) will execute now... // (2)之后的代码现在将执行...


As you can see from the explanation, try-catch blocks are the only way as dictated by C++ standards, to restore normal program control flow after an exception is thrown.从解释中可以看出, 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;
}

Even if the above code was legal, throw means control will leave the whole of the enclosing scope at the throw site.即使上面的代码是合法的, throw意味着控制将离开throw站点的整个封闭范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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