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 或任何其他编译器。
我一直在学习 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 或任何其他编译器。