【问题标题】:What happens if an exception is thrown from a function which was called inside other function?如果在其他函数内部调用的函数抛出异常会发生什么?
【发布时间】:2017-10-23 21:37:21
【问题描述】:

我对错误处理有一个疑问...

如果一个函数抛出一个异常并且该异常没有在主程序中被捕获,则会严重崩溃。

我的问题是为什么这个程序不会崩溃?如果从Test 抛出异常,函数enterNumber 也会抛出异常,即使它没有被捕获?

不应该将每个可能抛出异常的函数都放在 try-catch 块中,以防万一它抛出异常吗?

    #include <iostream>
    #include <stdexcept>

    void Test(int number) {
        if(number < 0)
            throw std::domain_error("Number is negative");
    }

    int enterNumber() {
        int number;
        std::cout << "Enter a number: ";
        std::cin >> number;
        Test(number);           
        return number;
    }

    int main() {
        try {
            int number = enterNumber();
            std::cout << "Entered number: " << number;
        }
        catch(std::domain_error e) {
            std::cout << e.what();
        }
        return 0;
    }

我觉得应该这样写:

void Test(int number) {
    if(number < 0)
        throw std::domain_error("Number is negative");
}

int enterNumber() {
    int number;
    std::cout << "Enter a number: ";
    std::cin >> number;
    try {
        Test(number);
    }
    catch(...) {
        throw;
    }
    return number;
}

int main() {
    try {
        int number = enterNumber();
        std::cout << "Entered number: " << number;
    }
    catch(std::domain_error e) {
        std::cout << e.what();
    }
    return 0;
}

如果有人能解释函数enterNumberTest 抛出异常时如何抛出异常? (案例1°)

谢谢你:)

【问题讨论】:

  • 按照 C++ 的设计工作。一个未捕获的函数在堆栈中冒泡。
  • 函数允许出现异常。一旦出现泡沫,问题就出现了。如果你没有从 main 中冒出,那你就没事了。
  • 您的try { Test(number); } catch(...) { throw; 构造完全没有意义。您捕获所有异常,然后立即重新抛出它们 - 就像您刚刚删除 try/catch 一样。
  • 异常会向上传播到调用堆栈。这是它的优点之一,记住传播错误的负担不在于开发人员。

标签: c++ exception error-handling try-catch throw


【解决方案1】:

您不需要从调用导致异常的函数的函数中捕获异常。实际上,最佳实践是从引发异常的站点尽可能(但不能更远)捕获异常,因为只有在程序的更高级别,您才有足够的信息来生成有意义的错误消息,和/或以其他方式处理异常。但是,应该在程序的某个级别捕获异常,否则程序将以不受控制的方式终止。

【讨论】:

  • 对于某些异常,让它们脱离 main 并关闭程序也可以。有时,崩溃(并为以后的调试编写内核)比试图从破碎的世界中恢复并可能造成更多伤害要好。
  • "最佳实践是尽可能从引发异常的站点捕获异常" 这对我来说似乎不正确,这意味着捕获main 或线程的 main 函数是捕获异常的最佳位置。也许诸如“最佳实践是仅在可以对其采取措施的情况下捕获异常”之类的内容。
  • @François 我说“尽可能”——在 main 中捕获和处理所有内容通常是不可能的。我稍微修改了答案。
  • @NeilButterworth 我还是不同意。这表明距离投掷越远越好。我想这听起来就像你在说你应该避免捕获一个你可以有意义地处理的异常,如果你知道另一个 catch 子句已经准备好在堆栈的更远处处理它。
  • @François 不,我不是这个意思,因为我认为您不需要了解程序的 catch 层次结构(如果有的话)。我提供了一种启发式方法(catch 尽可能远离 throw),因为经验告诉我,绝大多数程序员尽可能近地捕捉,吃掉异常,因此经常将他们的程序放入 UB 领域。
猜你喜欢
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
  • 2020-01-27
  • 1970-01-01
相关资源
最近更新 更多