13 September 2022

C++ 核心指南目录

C.37: Make destructors noexcept

理由

析构函数不能运行失败。析构函数如果尝试抛出异常,是设计上的一种错误。这时候最好直接终止程序。

注意

如果类的所以成员的析构函数都是 noexcept ,那么该类的析构函数(用户定义或编译器生成)也隐式地声明为 noexcept 。通过把析构函数标记为 noexcept ,就可以避免析构函数隐式的变成非 noexcept 。因为如果类的成员的析构函数不是 noexcept 的,就会导致该类的析构函数不再是 noexcept

例子

并非所有的析构函数都是默认 noexcept 的。类的某个成员的析构函数会抛出异常,就会影响整个类层级。

struct X {
    Details x;  // happens to have a throwing destructor
    // ...
    ~X() { }    // implicitly noexcept(false); aka can throw
};

因此,如果不确定,就把析构函数声明为 noexcept。

注意

为何不把所有析构函数都声明为 noexcept ?因为这样会看起来很杂乱。也就是说,能默认就默认,不要添加多余的代码。

强化

  • (简单)将析构函数标记为 noexcept ,如果函数可能会抛出异常。