我一直在学习C ++中的try-catch
块,我不理解catch
函数的语法。在cppreference上,它说如下:
1)在catch子句中声明形式参数:
catch (const std::exception& e) { /* */ }
2)声明一个未命名的参数:
catch (const std::exception&) { /* */ }
3)写一个" catch-all handler" (不确定这意味着什么),这是为任何异常激活的:
catch (...) { /* */ }
问题:
1)这些catch
块之间有什么区别?我不确定一个正式的参数,未命名的参数和一个"全能的处理程序"不同。
2)e
子句的参数catch
是什么类型的?它是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突然停止工作并崩溃。当抛出异常或我的代码不好时,我不知道这是否正常。
答案 0 :(得分:7)
catch (const std::exception& e) { /* */ }
如果希望能够访问catch块中的异常对象,则需要使用命名异常。例如,如果您想打印e.what()
。
catch (const std::exception&) { /* */ }
如果您不需要访问异常对象,则可以使用未命名的异常。也许你不关心异常的内容,你只想以同样的方式处理所有异常(这种类型)。
catch (...) { /* */ }
C ++允许您抛出任何类型的对象,无论它是否是从std::exception
派生的类型。这种类型的捕获块将捕获任何抛出的东西。就像未命名的异常一样,您将无法访问抛出的对象。但是,你甚至没有办法知道它是什么类型。
对于你的最后一个例子,我不认为这是你正在打印消息的catch块。毕竟,你正在捕捉错误的类型。一些编译器会自动插入异常捕获代码,它将捕获任何转义为main的内容,如果它是从std::exception
派生的类型,它将在终止程序之前打印what()
的结果。我相信GCC会这样做,但Visual Studio却没有。不确定Clang或任何其他编译器。