正确处理异常

Chr*_*nam 0 c++ error-handling try-catch throw

我的理解是,在现代 C++ 中,最好使用throw而不是返回错误代码。也就是说,如果我有一些功能:

void MyFunction(int foo, double bar){
    // Do some stuff....

    if (exception_criteria_met){
        throw "Call to MyFunction with inputs" << foo << " and " << bar << " failed because ...";
    }
};
Run Code Online (Sandbox Code Playgroud)

这是否意味着,为了正确处理这个问题,那么在所有调用 的函数中MyFunction,我必须实现如下所示的内容:

void MyOuterFunction(int foo){
    // Do some stuff...

    try {
        MyFunction(foo, bar);
    } catch (const char * exception_message) {
        throw "Call to MyOuterFunction with inputs " << foo << " failed because call to MyFunction with ....";
    };
Run Code Online (Sandbox Code Playgroud)

那么这是否意味着我必须对调用该函数调用堆栈的所有函数一直执行相同类型的错误处理?显然,在某些时候,也许其中一个函数实际上可以处理异常,并且不需要抛出自己的异常,但也许只是打印警告或类似的内容。但如何让其保持井然有序且易于理解呢?当许多功能相互交互时,从头到尾思考似乎是一件非常复杂的事情。

(作为第二个问题,如果MyFunction(foo,bar)要返回一个我想要使用的值,是不是意味着在离开try { }块后,返回的值将超出范围?这是否意味着我应该避免使用函数返回值,如果我会使用吗try-catch?)

for*_*818 7

我认为你的大部分问题要么过于宽泛,要么基于观点,或者两者兼而有之。然而,你的困惑似乎开始于

然后在调用 MyFunction 的所有函数中,我必须实现如下所示的内容:

那是不对的。

可能抛出异常的函数调用MyFunction可能如下所示:

void MyOuterFunction(int foo){
    // Do some stuff...
    MyFunction(foo, bar);
};
Run Code Online (Sandbox Code Playgroud)

如果您必须始终立即捕获异常,那么异常将是相当不切实际的。他们不是这样工作的。

简而言之:异常继续在调用堆栈中向上移动,直到您捕获它或main到达它但仍未捕获,在这种情况下程序终止。

没有固定的规则应该在哪里捕获异常。我个人的经验法则是在可以恢复的时候抓住它,但不能更早。有时候,根本没有达到预期是最可行的。接住然后重新扔很少有用,而且据我所知,只接住然后重新扔也没有任何用处。

  • 另一方面,当跨越库边界时,像其他东西一样捕捉和抛出可能非常有用。 (4认同)