从防护类析构函数抛出异常会导致std :: terminate

骨质疏松症

我正在尝试创建一个具有“几乎不变”的类,该类允许客户端在需要时打破不变,但前提是他们必须在离开令人讨厌的范围之前对其进行修复。

这是涉及的两个类。它类似于范围卫士。更多详细信息,评论和对ideone的小测试。

http://ideone.com/dMCHVU

class HCAccessor;

class HasConditions
{
    // class "mostly-invariant"
    // 7 < payload_ <42
    int payload_;

    bool valid() const
    {
        if (!(7 < payload_) || !(payload_ < 42))
            return false;
        else
            return true;
    }

public:
    HasConditions(const int payload)
        : payload_(payload)
    {
        if (!valid())
        {
            throw std::runtime_error("can't construct");
        }
    }

    friend class HCAccessor;
};

class HCAccessor
{
    HasConditions& hc_;

public:
    HCAccessor(HasConditions& hc)
        : hc_(hc)
    {}

    HCAccessor(HCAccessor& other)
        : hc_(other.hc_)
    {}

    ~HCAccessor()
    {
        if (!hc_.valid())
        {
            throw std::runtime_error("you broke it!");
        }
    }

    void payload(const int newval)
    {
        hc_.payload_ = newval;
    }

    int payload() const
    {
        return hc_.payload_;
    }
};

当“几乎不变”被破坏然后修复时,代码似乎可以正常工作。当“几乎不变”保持破裂并~HCAccessor()抛出时,std::terminate被调用,我不知道为什么。导致std::terminate呼叫的异常原因似乎都不适合。

http://en.cppreference.com/w/cpp/error/terminate

据我所知,只有一个异常被抛出,然后立即std::terminate被调用。

为什么会发生这种情况,我该如何解决?

温特穆特

noexcept默认情况下,C ++ 11中析构函数是如果您确实想这样做,则必须使用以下方法声明HCAccessor的析构函数noexcept(false)

~HCAccessor() noexcept(false) {

或老式的抛出清单:

~HCAccessor() throw(std::runtime_error) {

(对于Pradhan来说noexcept(false),我以前从未见过语法表示敬意。我想这不是人们经常需要的东西)。

但是,这样做几乎可以肯定是Bad Idea™飞行异常导致析构函数在堆栈展开时被调用,并且如果您有引发异常的析构函数,您最终会发现自己试图同时抛出多个异常。爆炸。

如果的实例HCAccessor不管理任何资源,则它在清理中无事可做,并且析构函数为nop。我不认为这是引发异常的原因-顺其自然。

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

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

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

RAII类的析构函数抛出异常

来自分类Dev

从noexcept函数参数的构造函数引发的异常是否会立即导致对std :: terminate()的调用?

来自分类Dev

swbemobjectex类的幽灵/隐藏方法(例如.Terminate)

来自分类Dev

类中std :: vector的析构函数

来自分类Dev

编写死亡测试以验证std :: set_terminate行为

来自分类Dev

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

来自分类Dev

从析构函数中抛出异常对于vtable是安全的吗?

来自分类Dev

处理析构函数内部的异常(但不抛出)

来自分类Dev

noexcept函数返回具有抛出析构函数的类

来自分类Dev

类析构函数导致重载+运算符的问题

来自分类Dev

析构函数引发异常

来自分类Dev

C ++清除类析构函数中的std :: list结构

来自分类Dev

基类中的非虚拟析构函数,但派生类中的虚拟析构函数导致分段错误

来自分类Dev

返回类析构函数

来自分类Dev

如何检测构造函数是否为带有抛出析构函数的异常

来自分类Dev

析构函数抛出System.NullReferenceException

来自分类Dev

一个小型clang项目上的std :: terminate()链接器错误

来自分类Dev

如何将Std :: set_terminate与SetUnhandledExceptionFilter一起使用?

来自分类Dev

Phoenix 1.4 升级 - (FunctionClauseError) Phoenix.Socket.__terminate__/2 中没有匹配的函数子句

来自分类Dev

抛出未处理的异常后过早离开的析构函数是否可以释放成员数据?

来自分类Dev

抛出异常时不执行析构函数(不展开堆栈)

来自分类Dev

抛出未处理的异常后过早离开的析构函数是否可以释放成员数据?

来自分类Dev

为什么我无法处理从析构函数外部抛出的异常?

来自分类Dev

在某些情况下,使用std :: set_terminate无法捕获C ++纯虚函数调用吗?

来自分类Dev

std:map析构函数会调用键析构函数还是值析构函数?

来自分类Dev

how to terminate qthread in python

来自分类Dev

为什么C ++不使用std :: nested_exception允许从析构函数中抛出?

来自分类Dev

std :: vector中的元素可能具有抛出的析构函数吗?

来自分类Dev

为什么C ++不使用std :: nested_exception允许从析构函数中抛出?

Related 相关文章

  1. 1

    RAII类的析构函数抛出异常

  2. 2

    从noexcept函数参数的构造函数引发的异常是否会立即导致对std :: terminate()的调用?

  3. 3

    swbemobjectex类的幽灵/隐藏方法(例如.Terminate)

  4. 4

    类中std :: vector的析构函数

  5. 5

    编写死亡测试以验证std :: set_terminate行为

  6. 6

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

  7. 7

    从析构函数中抛出异常对于vtable是安全的吗?

  8. 8

    处理析构函数内部的异常(但不抛出)

  9. 9

    noexcept函数返回具有抛出析构函数的类

  10. 10

    类析构函数导致重载+运算符的问题

  11. 11

    析构函数引发异常

  12. 12

    C ++清除类析构函数中的std :: list结构

  13. 13

    基类中的非虚拟析构函数,但派生类中的虚拟析构函数导致分段错误

  14. 14

    返回类析构函数

  15. 15

    如何检测构造函数是否为带有抛出析构函数的异常

  16. 16

    析构函数抛出System.NullReferenceException

  17. 17

    一个小型clang项目上的std :: terminate()链接器错误

  18. 18

    如何将Std :: set_terminate与SetUnhandledExceptionFilter一起使用?

  19. 19

    Phoenix 1.4 升级 - (FunctionClauseError) Phoenix.Socket.__terminate__/2 中没有匹配的函数子句

  20. 20

    抛出未处理的异常后过早离开的析构函数是否可以释放成员数据?

  21. 21

    抛出异常时不执行析构函数(不展开堆栈)

  22. 22

    抛出未处理的异常后过早离开的析构函数是否可以释放成员数据?

  23. 23

    为什么我无法处理从析构函数外部抛出的异常?

  24. 24

    在某些情况下,使用std :: set_terminate无法捕获C ++纯虚函数调用吗?

  25. 25

    std:map析构函数会调用键析构函数还是值析构函数?

  26. 26

    how to terminate qthread in python

  27. 27

    为什么C ++不使用std :: nested_exception允许从析构函数中抛出?

  28. 28

    std :: vector中的元素可能具有抛出的析构函数吗?

  29. 29

    为什么C ++不使用std :: nested_exception允许从析构函数中抛出?

热门标签

归档