【问题标题】:Do you need to know what exception is going to occur to handle them in C++?您是否需要知道在 C++ 中处理它们会发生什么异常?
【发布时间】:2021-12-06 07:32:09
【问题描述】:

在异常处理中,你需要知道什么异常,哪里会发生异常吗?您能否编写一个代码来打印并通知我们程序中某处发生了异常。我的意思是我有一个程序,我不知道是否会发生异常,如果发生异常,那么它将打印以通知我们。

【问题讨论】:

  • 您能提供更多细节吗?就像您要在其中检查异常的代码 sn-p 一样。通常,您可以使用 trycatch 在 C++ 中捕获异常,但这实际上取决于您的代码如何最好地应用它。
  • 需要吗?严格来说,没有。可以catch 抛出任何异常,但这是最后的手段。如果您有可以抛出异常的代码,您应该知道可以抛出哪些异常。然后,您可以降低它们被抛出的可能性,或者至少捕获特定异常并为您的团队提供更有意义的诊断。
  • 是的,但是如果我不知道会发生什么异常,那么我应该在 throw 部分给出什么参数?

标签: c++ exception


【解决方案1】:

异常处理是您应该设计的,事实上它与 RAII (https://en.cppreference.com/w/cpp/language/raii) 一起工作得很好。 (Notr 在使用异常的嵌入式平台上,由于一些运行时开销而不那么流行)。我个人喜欢异常的地方在于它将错误处理与正常的程序流程分开(如果操作正确,几乎不会有任何 if then else 检查)

// Exception handling should be part of your overal design.And many standard library functions can throw exceptions, It is always up to you where you handle them.

#include <iostream>
#include <string>
#include <stdexcept>

int get_int_with_local_exception_handling()
{
    do
    {
        try
        {
            std::cout << "Input an integer (local exception handling, enter a text for exception): ";
            std::string input;
            std::cin >> input;

            // stoi is a function that can throw exceptions
            // look at the documentation https://en.cppreference.com/w/cpp/string/basic_string/stol
            // and look for exceptions. 
            // 
            int value = std::stoi(input);

            // if input was ok, no exception was thrown so we can return the value to the client.
            return value;
        }
        // catch by const reference, it avoids copies of the exception
        // and makes sure you cannot change the content
        catch (const std::invalid_argument& e)
        {
            // std::exceptions always have a what function with readable info
            std::cout << "handling std::invalid_argument, " << e.what() << "\n";
        }
        catch (const std::out_of_range& e)
        {
            std::cout << "handling std::out_of_range, " << e.what() << "\n";
        }
    } while (true);
}

int get_int_no_exception_handling()
{
    std::cout << "Input an integer (without exception handling, enter a text for exception): ";
    std::string input;
    std::cin >> input;

    int value = std::stoi(input);
    return value;
}


int main()
{
    try
    {
        // this function shows you can handle exceptions locally
        // to keep program running
        auto value1 = get_int_with_local_exception_handling();
        std::cout << "your for input was : " << value1 << "\n";

        // this function shows that exceptions can be thrown without
        // catching, but then the end up on the next exception handler
        // on the stack, which in this case is the one in main
        auto value2 = get_int_no_exception_handling();
        std::cout << "your input was : " << value1 << "\n";

        return 0;
    }
    catch (const std::exception& e)
    {
        std::cout << "Unhandled exception caught, program terminating : " << e.what() << "\n";
        return -1;
    }
    catch (...)
    {
        std::cout << "Unknown, and unhandled exception caught, program terminating\n";
    }
}

【讨论】:

  • 在您的示例中,您知道可能会引发哪些异常,但 OP 询问如何处理未知异常。我希望提到catch(...)
  • 添加了,这仍然留下了真正的坏问题,比如内存访问违规,它仍然不会被捕获。在这里,内存转储分析方法开始发挥作用。
  • 好点。通常 c++ 异常与来自某个深处的异常混淆
  • 是的 C++ 异常应该用于处理预期的异常,并且可以设计用于其他异常(如访问冲突)通常是编程错误(并且确实应该导致崩溃,越早越好,因为程序无论如何都处于不确定状态)
【解决方案2】:

是和不是。

不,因为通过throw some_exception; 抛出的任何异常都可以通过catch(...) 捕获。

是的,因为catch(...) 不是很有用。你只知道有一个例外,但没有更多。

通常,异常会携带有关您要在 catch 中使用的原因的信息。仅作为最后的手段或当您需要绝对确保不会错过任何异常时,您应该使用catch(...)

 try {
      might_throw_unknown_exceptions();
 } catch(std::exception& err) {
      std::cout << "there was a runtime error: " << err.what();
 } catch(...) {
      std::cout << "an unknown excpetion was thrown.";
 }

C++ 标准库很少使用继承。 Exceptions 只是广泛使用的地方:所有标准异常都继承自 std::exception,最好也继承自它的自定义异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 2012-12-02
    • 2017-09-29
    • 2020-12-03
    • 2011-11-08
    相关资源
    最近更新 更多