C++11 异常的析构函数允许现在抛出?

C++11 Exception's destructor allows to throw now?

本文关键字:许现 异常 析构函数 C++11      更新时间:2023-10-16

知道为什么吗virtual ~exception() throw()在c++ 98中,但virtual ~exception()在c++ 11中?

允许c++ 11抛出类exception的析构函数的设计决策是什么?

从这里

:

c++ 98:

class exception {
public:
  exception () throw();
  exception (const exception&) throw();
  exception& operator= (const exception&) throw();
  virtual ~exception() throw();
  virtual const char* what() const throw();
}
c++ 11:

class exception {
public:
  exception () noexcept;
  exception (const exception&) noexcept;
  exception& operator= (const exception&) noexcept;
  virtual ~exception();
  virtual const char* what() const noexcept;
}

是什么设计决定使得c++ 11允许抛出类exception的析构函数?

没有这样的设计决策(幸运的是!)在c++ 11中,即使显式声明的析构函数也默认限定为noexcept。这可以从c++ 11标准的第12.4/3段得到证明:

没有异常规范的析构函数声明被隐式地认为具有异常规范异常规范与隐式声明(15.4)相同。

从第15.4/14段,其中指定了隐式声明具有的异常规范:

继承构造函数(12.9)和隐式声明的特殊成员函数(第12条)具有异常规范。如果f是继承构造函数或隐式声明的默认构造函数,则复制构造函数、移动构造函数、析构函数、复制赋值操作符或移动赋值操作符,其隐式exception-specification当且仅当例外规范允许T时指定类型id T由f的隐式定义直接调用的函数;f允许所有的异常,如果任何函数直接调用允许所有异常,并且 f具有异常规范noexcept(true),如果每个函数都直接调用它

加在一起,以上两段保证(给定你引用的exception的析构函数的声明)exception的析构函数不会抛出。

这在c++ 11标准的18.8.1/7-8段中也有明确的规定:

virtual ~exception();

7 Effects:销毁类exception的对象。

8 备注: 不抛出任何异常

注意,动态异常规范(如throw())在c++ 11中已弃用。根据附件D第D.4/1条:

不赞成使用dynamic-exception-specifications