为什么来自unique_ptr析构函数的异常会终止程序?

阿敏

看一下这段代码,该代码使程序终止而不捕获异常。

#include <iostream>
#include <string>
#include <memory>
#include <stdexcept>
using namespace std;

struct test {
  ~test() noexcept(false) {
    throw runtime_error("-my-cool-exception-");
  }
};

int main()
{
  try {
    auto ptr = unique_ptr<test>(new test());
    //test t; // this is ok, without unique_ptr<test> it works fine.
  }
  catch(exception& e) {
    cout << "this is not called, the program is aborted";
    cout << e.what() << endl;
  }
  return 0;
}

这个问题与堆栈溢出问题不同:将异常抛出析构函数

区别在于仅在使用unique_ptr<test>异常时才捕获该异常。

您可以在此处查看实时代码,进行编辑和编译http://cpp.sh/9sk5m

友人

这是标准要求的。根据unique.ptr.single.dtor,20.10.1.2.2.1

要求:表达式get_deleter()(get())应当格式正确,应具有明确定义的行为,并且不得引发异常[注意:使用default_delete要求T为完整类型。—尾注]

(强调我的)

因此,实际上,析构函数本身是否具有无关紧要noexcept(false)禁止在这种情况下抛出–最后的单词。

通常情况就是这样std::-除非另有说明。根据res.on.functions,17.6.4.8.2.4

特别是在以下情况下,效果是不确定的:[...]如果任何替换函数或处理函数或析构函数操作通过异常退出,除非适用的Required behavior:段中特别允许

(强调我的)

注意:通常,您可以使用抛出析构函数noexcept(false)但是,这是非常危险的,因为std::terminate如果堆栈由于抛出异常而正在展开则会被调用根据except.ctor,15.2.1

当控制权从抛出异常的点传递到处理程序时,析构函数由本节中指定的进程调用,该进程称为堆栈展开。如果由堆栈展开直接调用的析构函数异常退出,则调用std :: terminate([except.terminate])。[注意:因此,析构函数通常应捕获异常,而不应将其传播到析构函数之外。—尾注]

(强调我的)

在Coliru上实时观看

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么在使用unique_ptr时没有调用析构函数?

unique_ptr析构函数的优势

std :: unique_ptr析构函数构造函数顺序

unique_ptr :: release()是否调用析构函数?

使用unique_ptr保护的析构函数

unique_ptr 两次调用析构函数

如果A有析构函数,std :: unique_ptr <A>什么时候需要特殊的删除器?

为什么要为具有非平凡析构函数的类声明constrexpr构造函数(例如unique_ptr,std :: variant)

为什么通过添加空的析构函数来修复“错误:使用unique_ptr将'sizeof'无效应用到不完整类型”的问题?

为什么C ++偏向于析构函数的异常?

std :: unique_ptr是否在其析构函数中将其基础指针设置为nullptr?

用于 pimpl 的 Unique_ptr 用法 - 即使声明了析构函数也不会编译

std::unique_ptr 在虚拟析构函数上重置 SIGABRT

当包含它的对象调用其析构函数时,unique_ptr是否会取消分配?

在具有受保护的析构函数的类中使用unique_ptr

thread_local std :: unique_ptr版本未调用析构函数

静态unique_ptr两次调用析构函数

具有unique_ptr成员和自定义析构函数的对象的向量

当基类具有受保护的析构函数时,创建unique_ptr <Base>

std :: unique_ptr的自定义删除程序是否是手动调用析构函数的有效位置?

为什么在构造函数调用异常后不释放unique_ptr?

如何允许 std::unique_ptr 访问类的私有析构函数或使用私有析构函数实现 C++ 工厂类?

是unique_ptr构造函数初始化原始指针,还是unique_ptr析构函数删除关联的原始指针?

使用std :: map时,包含unique_ptr的结构中的默认析构函数会导致编译错误

C ++,静态对象构造函数中的异常会绕过先前静态对象的析构函数

为什么在插入析构函数时总是得到“在抛出...实例后终止调用”?

为什么析构函数挂起

为什么要调用析构函数

为什么不调用析构函数?

TOP 榜单

热门标签

归档