1. 什么是异常?什么时候会抛出异常?什么时候需要代码异常安全的保证?为什么需要异常安全?异常的产生、捕捉、处理、传递?
给出没有异常安全保证的代码的实例与分析
C++ 标准的异常
C++ 提供了一系列标准的异常,定义在 <exception> 中,我们可以在程序中使用这些标准的异常。它们是以父子类层次结构组织起来的,如下所示:
std::exception 该异常是所有标准 C++ 异常的父类。
std::bad_alloc 该异常可以通过 new 抛出。
std::bad_cast 该异常可以通过 dynamic_cast 抛出。
std::bad_exception 这在处理 C++ 程序中无法预期的异常时非常有用。
std::bad_typeid 该异常可以通过 typeid 抛出。
std::logic_error 理论上可以通过读取代码来检测到的异常。
std::domain_error 当使用了一个无效的数学域时,会抛出该异常。
std::invalid_argument 当使用了无效的参数时,会抛出该异常。
std::length_error 当创建了太长的 std::string 时,会抛出该异常。
std::out_of_range 该异常可以通过方法抛出,例如 std::vector 和 std::bitset<>::operator。
std::runtime_error 理论上不可以通过读取代码来检测到的异常。
std::overflow_error 当发生数学上溢时,会抛出该异常。
std::range_error 当尝试存储超出范围的值时,会抛出该异常。
std::underflow_error 当发生数学下溢时,会抛出该异常。
2. 什么是异常安全?异常安全的等级有哪些?
一段代码是异常安全的,如果这段代码运行时的失败不会产生有害后果,如内存泄露、存储数据混淆、或无效的输出。
异常中立性
是指当你的代码(包括你调用的代码)引发异常时,这个异常能保持原样传递到外层调用代码
异常安全性
- 抛出异常后,资源不泄露
- 抛出异常后,不会使原有数据恶化(例如正常指针变野指针)
异常安全等级
不抛异常保证(no throw guarantee) > 强烈保证(the strong guarantee) > 基本保证(the basic guarantee)> 无泄漏保证(no-leak guarantee) > 异常不安全(no exception safety)
3. 如何保证代码实现(设计)符合某个异常安全等级?
不抛出保证 只使用内置类型,使用noexcept关键字
强烈保证 copy-and-swap
基本保证 RAII 智能指针
4. 异常安全的低层实现原理与开销计算?
栈回退(未完待续)