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

时间:2018-02-04 01:00:20

标签: c++ exception exception-handling

我一直在学习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突然停止工作并崩溃。当抛出异常或我的代码不好时,我不知道这是否正常。

1 个答案:

答案 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或任何其他编译器。