C++:noexcept(或throw())虚拟析构函数=默认值;

ikh*_*ikh 5 c++ destructor

下面的代码合法吗?

class C
{
    virtual ~C() noexcept = default;
};
Run Code Online (Sandbox Code Playgroud)

或者

class C
{
    virtual ~C() throw() = default;
};
Run Code Online (Sandbox Code Playgroud)

(throw() 已弃用,但我的编译器不支持 noexcept ;;)

Jos*_*eld 4

\n

8.4.2 [dcl.fct.def.default]显式默认函数 [...] 仅当与异常规范 (15.4) 兼容时才可以具有显式异常规范隐式声明上的 \xac\x81cation。

\n
\n\n
\n

15.4/3 [ except.spec]两个异常规范在以下情况下是兼容的:

\n
    \n
  • 无论其形式如何,两者都是非投掷的(见下文),
  • \n
  • 两者都具有 noexcept(constant-expression) 形式,并且常量表达式是等效的,或者
  • \n
  • 两者都是动态异常规范\xef\xac\x81cations,具有相同的调整类型集。
  • \n
\n
\n

因此,只有当它与析构函数的隐式声明完全匹配时,您才能给出显式异常规范。

\n

隐式析构函数的异常规范取决于它调用的函数:

\n
\n

15.4/14 [ except.spec]隐式声明的特殊成员函数应具有异常规范。如果 f 是隐式声明的 [...] 析构函数,[...] 其隐式异常指定\xef\xac\x81cation 指定\xef\xac\x81es 类型 ID T 当且仅当 T 被允许时由 f\xe2\x80\x99s 隐式 de\xef\xac\x81nition 直接调用的函数的异常规范\xef\xac\x81cation;如果 f 直接调用的任何函数允许所有异常,则 f 应允许所有异常;如果 f 直接调用的每个函数都不允许异常,则 f 应不允许任何异常。

\n
\n

析构函数调用的函数是类的非静态数据成员、其基类及其虚拟基类的析构函数。

\n

在您的情况下,由于该类没有数据成员,也没有基类,因此它不调用任何函数,因此它属于最后一种情况。它直接调用的每个函数(没有)都不允许出现异常,因此该析构函数必须不允许出现异常。因此,您的异常规范必须是非抛出的,因此nothrowexcept()、 和exception(constant expression that yields true)是您可以给出的唯一合适的异常规范,因此您的代码没有问题。

\n