过渡到 C++11,其中析构函数使用 noexcept 隐式声明

2024-02-18

在 C++11 中,没有任何异常规范的析构函数隐式声明为noexcept,这是对 C++03 的更改。因此,在 C++03 中从析构函数抛出的代码在 C++11 中仍然可以正常编译,但一旦尝试从这样的析构函数抛出,就会在运行时崩溃。

既然这样的代码不存在编译时错误,那么如果不将代码库中的所有现有析构函数声明为noexcept(false),这确实过于冗长和侵入性,或者检查每个析构函数是否有可能抛出,这将非常耗时且容易出错,或者在运行时捕获并修复所有崩溃,这永远无法保证所有此类案例都被发现了吗?


请注意,规则实际上并没有那么残酷。析构函数只会是隐式的noexcept如果隐式声明的析构函数是。因此,将至少一个基类或成员类型标记为noexcept (false)会中毒noexcept整个层次结构/聚合的性质。

#include <type_traits>

struct bad_guy
{
  ~bad_guy() noexcept(false) { throw -1; }
};

static_assert(!std::is_nothrow_destructible<bad_guy>::value,
              "It was declared like that");

struct composing
{
  bad_guy member;
};

static_assert(!std::is_nothrow_destructible<composing>::value,
              "The implicity declared d'tor is not noexcept if a member's"
              " d'tor is not");

struct inheriting : bad_guy
{
  ~inheriting() { }
};

static_assert(!std::is_nothrow_destructible<inheriting>::value,
              "The d'tor is not implicitly noexcept if an implicitly"
              " declared d'tor wouldn't be.  An implicitly declared d'tor"
              " is not noexcept if a base d'tor is not.");

struct problematic
{
  ~problematic() { bad_guy {}; }
};

static_assert(std::is_nothrow_destructible<problematic>::value,
              "This is the (only) case you'll have to look for.");

尽管如此,我还是同意克里斯·贝克 https://stackoverflow.com/a/32956495/1392132你迟早应该摆脱你的抛出析构函数。它们还可能使您的 C++98 程序在最不方便的时候崩溃。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

过渡到 C++11,其中析构函数使用 noexcept 隐式声明 的相关文章

随机推荐