C++ - 不理解 try-catch 中 catch 函数的语法

C++ - Do not understand the syntax of the catch function in try-catch

我一直在学习 C++ 中的 try-catch 块,但我不理解 catch 函数的语法。在 cppreference 上,它表示如下:

1) 在catch子句中声明形参:

catch (const std::exception& e) { /* */ }

2) 声明一个未命名的参数:

catch (const std::exception&) { /* */ }

3) 写一个"catch-all handler"(不知道这是什么意思),任何异常都会激活:

catch (...) { /* */ }

问题:

1) 这些catch块有什么区别?我不确定形式参数、未命名参数和 "catch-all handler" 有何不同。

2) catch 子句的参数e 是什么类型?是 exception 类型吗?除了在如何编写 try-catch 块的示例中,我从未见过这种类型。如果是这样,我如何在 catch 子句中使用它来输出错误消息? e 可以接受我在抛出错误时发送的字符串吗?

3) 我已经试验并编写了一个 try-catch 块,如下所示:

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

try
{
    throw invalid_argument("Error, program stopped.");
}

catch(const string& e)
{
    cout << e;
}

此代码成功调用 catch 块并打印我的消息:"Error, program stopped."。但是,.exe 突然停止工作并崩溃。不知道这是抛出异常时的正常情况,还是我的代码有问题

catch (const std::exception& e) { /* */ }

如果您希望能够访问 catch 块中的异常对象,则需要使用命名异常。例如,如果你想打印 e.what().

catch (const std::exception&) { /* */ }

如果您不需要访问异常对象,您可以使用未命名的异常。也许你并不关心异常的内容,你只是想以相同的方式处理所有(这种类型的)异常。

catch (...) { /* */ }

C++ 允许您抛出任何类型的对象,无论它是否是从 std::exception 派生的类型。这种类型的 catch 块将捕获任何抛出的东西。就像未命名的异常一样,您将无权访问抛出的对象。而且,你甚至无法知道它是什么类型。

对于您的最后一个示例,我认为不是您的 catch 块正在打印消息。毕竟,你抓错了类型。一些编译器会自动插入异常捕获代码,捕获任何从 main 转义的内容,如果它是从 std::exception 派生的类型,它将在终止程序之前打印 what() 的结果。我相信 GCC 会这样做,但 Visual Studio 不会。不确定 Clang 或任何其他编译器。