首页 理论教育 C++异常处理语法:从入门到精通

C++异常处理语法:从入门到精通

时间:2023-08-20 理论教育 版权反馈
【摘要】:动手写13.1.1动手写13.1.1展示了异常处理的语法和行为。运行结果如图13.1.1所示:图13.1.1异常处理在示例中,我们定义了两个不相关的类,并尝试用dynamic_cast来进行类型转换。try-catch块是异常处理的基本结构。图13.1.2未经处理的异常在catch块中我们可以编写处理异常的代码,而在这里我们直接调用异常对象的what()函数来获取错误信息,并通过cerr打印到标准输出中。

C++异常处理语法:从入门到精通

我们可以自己定义异常对象,而C++标准库中的函数本身已经会抛出各种各样的预置异常了。我们来看看这些异常是如何被捕获的。

动手写13.1.1

动手写13.1.1展示了异常处理的语法和行为。运行结果如图13.1.1所示:

图13.1.1 异常处理

在示例中,我们定义了两个不相关的类,并尝试用dynamic_cast来进行类型转换。在指针的情况下,dynamic_cast会返回空指针,而在引用的情况下,dynamic_cast就会抛出异常。

try-catch块是异常处理的基本结构。catch块的开头会定义需要捕获的异常对象,而这个异常对象一定是从try块中的代码抛出的。如果这个转换发生在try块之外,由于异常没有被处理,就会发生程序崩溃,并且在调试模式运行时编译器会提示存在着未经处理的异常,如图13.1.2所示。

图13.1.2 未经处理的异常(www.xing528.com)

在catch块中我们可以编写处理异常的代码,而在这里我们直接调用异常对象的what()函数来获取错误信息,并通过cerr打印到标准输出中。

在抛出异常之后,如果紧跟着的catch块能够处理相应的异常那就再好不过了,但如果不能,程序也会顺着函数调用栈寻找外层函数中的catch块,这个过程也叫作栈展开(Stack Unwinding),当然这也需要外层函数处于try块之中。当程序一层层往外但最终没找到匹配的catch块时,就会调用标准库的terminate()函数,而terminate()函数会调用abort()函数结束程序,也就出现了之前“未经处理的异常”的情况。

此外,在catch块处理完异常之后,程序会跳转到与当前匹配catch块连续的所有catch块之后继续运行。这是因为try块后面可以紧跟好几个catch块,也就是说栈展开的过程是先搜索与当前try块相邻的所有catch块,再往上进入到外层函数重复这样的搜索。下面的示例展示了几个catch块连在一起的情况:

动手写13.1.2

动手写13.1.2展示了略为复杂的栈展开的情况,运行结果如图13.1.3所示:

图13.1.3 栈展开

这个示例中包含好几个语法知识点。我们在匹配runtime_error异常的catch块之后又加了一个括号内只有3个点的catch块,这样的catch块也叫作捕获所有异常(Catch-All)块。在第一个catch没有捕获到异常之后,这个catch块捕获到了异常。要注意在搜索匹配catch的时候是只要找到能够处理的就进入执行,所以catch-all块一般要放在最后,而基类的异常对象也要放在派生类异常对象之后。

在catch-all块捕获到异常之后,程序调用了空的throw语句,这表示重新抛出异常。这个语句只能出现在catch块或catch块调用的函数中,重新抛出的异常将继续按着栈展开的规律搜索匹配catch块。在这里我们就匹配到了外层main()函数中的catch块,并成功地处理了。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈