- C++异常处理:基础语法详解
- noexcept 修饰符与运算符的精准运用
- 异常修饰符与指针、虚函数的交互关系
- 探秘C++标准异常类
本文专注于阐述C++异常机制的语法及其运用,至于C++异常机制的实现细节,我们将在后续的篇章中展开讨论。
- C++中异常处理的基本框架
- 深入理解throw与try...catch语句
在C++中,我们通过throw语句和try...catch语句组合来实现异常处理。throw语句的作用是抛出异常,其后的表达式代表了一个异常对象,其值的类型可以是基础数据类型或自定义的类。
try...catch语句的构造如下:
catch块可以有多个,但至少要有一个存在。其执行流程是:
- 执行try块中的代码,如果在执行过程中没有发生异常,则执行完try块后直接跳转到最后一个catch块之后的代码;如果try块中发生了异常,则会立即跳转到第一个与抛出异常类型匹配的catch块中执行。
- 如果try块中的异常无法在内部的catch块中得到处理,那么它会逐层向外层try...catch结构传递,直至到达程序的点main()函数。如果仍然没有找到合适的处理方式,程序最终会调用terminate()函数来终止执行。
- 当在某个try...catch...块内找不到与抛出异常对象匹配的catch语句时,异常将由外部的try...catch...块来处理。这个过程会一直持续,直到所有可能的处理方式都被考虑过。
若希望捕获所有类型的异常,可以使用如下的catch块结构:
noexcept修饰符与运算符的详解
noexcept修饰符用于告知编译器或开发者一个函数是否会抛出异常。此信息有助于编译器进行优化以及给调用者提供清晰的预期。
关键字noexcept紧跟在函数参数列表的后面。在成员函数中,noexcept修饰符需要位于const和引用限定符之后,以及final、override或虚函数的=0之前。
关于违反异常承诺的注意事项
值得注意的是,编译器在编译时不会检查noexcept说明的准确性。即使一个函数被标记为noexcept而实际上可能抛出异常或调用可能抛出异常的其他函数,编译器仍然会认为它是正确的。一旦一个标记为noexcept的函数实际上抛出了异常,程序将调用std::terminate()来确保遵守程序不抛出未获的异常的承诺。
noexcept运算符的应用
noexcept运算符是一个一元运算符,返回一个bool值,用于判断给定的表达式是否会抛出异常。此运算符在模板编程中尤为有用。
异常修饰符与指针、虚函数的交互
在C++中,基类的虚函数如果承诺不抛出异常,则派生类的同名虚函数也必须承诺不抛出异常。反之,如果基类虚函数未做此承诺,派生类函数则可以自由选择是否承诺。
C++标准异常类的探索
C++标准库中定义了一系列的异常类,如bad_typeid、bad_cast、bad_alloc等,都是exception类的派生类。在使用这些异常类时,需要包含相应的头文件<exception>。