繁体   English   中英

C++ 如果抛出异常且该异常与捕获的异常类型不匹配,则 try-catch 语句的行为是什么?

[英]C++ What is the behavior of a try-catch statement if an exception is thrown, and that exception does not match the type of exception caught?

我有兴趣进一步了解以下代码逻辑的行为方式:

try
{
    // might, or might not do this: throw ExceptionTypeA;
    function_which_might_throw_exception_type_a();
    
    do_A(); // do we do A?
}
catch(ExceptionTypeB)
{
    // B will never be done
    do_not_do_B();
}

// C is always done (Edit: should always be done, but actually isn't)
do_C();

简而言之,这个问题可以简单表述为:function do_A会被调用吗?*

*[如果function_which_might_throw_exception_type_a()确实throw ExceptionTypeA; ...当然很清楚,如果function_which_might_throw_exception_type_a()没有抛出异常,就会调用do_A() 。]

上面的伪代码应该表示抛出的异常类型与catch子句中捕获的异常类型不同。

换句话说,虽然有catch子句,但这里不会捕获异常,因为它不是正确的类型。

在这种情况下,编译器是生成一个 output 来完全跳过对do_A()的调用,还是编译器生成一个 output 其中调用了do_A() () ?

我相当有信心,如果在 try 块中抛出任何异常,那么执行路径是立即离开 try 块。 也就是说,我认为上面的伪代码中并没有调用do_A() (假设 function function_which_might_throw_exception_type_a()确实抛出ExceptionTypeA 。)

但是我想检查一下,因为我开始怀疑了。

仅供参考:我正在看一段代码,更明智地写成:

try
{
    // might, or might not do this: throw ExceptionTypeA;
    function_which_might_throw_exception_type_a();
    
    do_A(); // do we do A?

    // C **should** always be done
    do_C()
}
catch(ExceptionTypeB)
{
    // B will never be done
    do_not_do_B();
}
return something;

但是,我认为这不等同于第一个伪代码。

由于C++没有try-catch-finally类型的语句,所以不能这样表达逻辑。 (但我认为如果可以的话会更好。)

会调用 function do_A 吗?

简而言之——不。 try块内抛出异常时,该块将立即退出。 如果抛出的异常类型未由相应的catch块处理,那么它将被处理得非常像在try块外抛出的异常(可能导致堆栈展开,但最终导致程序终止)。

如果你希望你的do_C() function 被称为“总是”,无论抛出什么类型的异常,那么你应该在你的其他具体之后添加一个catch(...) (称为“catch-all clause”)块catch块。 这可以是一个空语句/块; 如果是这样,抛出的异常仍会被捕获(即不会进一步传播),但不会采取任何特定操作。

实现您想要的东西的一种可能方法如下:

try
{
    // might, or might not do this: throw ExceptionTypeA;
    function_which_might_throw_exception_type_a();
    
    do_A(); // If the above throws, this WILL NOT be executed
}
catch(ExceptionTypeB)
{
    // B will never be done
    do_not_do_B();
}
catch(...) {} // This will catch "ExceptionTypeA" but do nothing about it ...
do_C();       // Will 'always' execute (unless an earlier catch re-throws)
return something;

暂无
暂无

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

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