当在析构函数中引发异常时,为什么不调用过载的删除? [英] Why is an overloaded delete not called when an exception is thrown in a destructor?

查看:124
本文介绍了当在析构函数中引发异常时,为什么不调用过载的删除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了以下代码,这些代码重载了 new delete 运算符,并在析构函数中引发异常

I've written the below code which overloads the new and delete operators and throws an exception in the destructor.

引发异常时,为什么未执行 delete 运算符中的代码(并且再见

When the exception is thrown, why is the code in the delete operator not executed (and "bye" printed)?

如果不应该执行,(如何)释放内存?是其他删除运算符叫什么?重载其中之一会导致执行相应的代码吗?还是仅仅是因为失败的销毁意味着也许不应该释放内存?

If it shouldn't be executed, (how) is the memory freed? Is one of the other delete operators called? Would overloading one of them instead result in the corresponding code being executed? Or is the memory simply not freed because a failed destruction implies that maybe it shouldn't be?

#include <iostream>
using namespace std;
class A
{
public:
    A() { }
    ~A() noexcept(false) { throw exception(); }
    void* operator new (std::size_t count)
    {
        cout << "hi" << endl;
        return ::operator new(count);
    }
    void operator delete (void* ptr)
    {
        cout << "bye" << endl;
        return ::operator delete(ptr);
    }
    // using these (with corresponding new's) don't seem to work either
    // void operator delete (void* ptr, const std::nothrow_t& tag);
    // void operator delete (void* ptr, void* place);
};

int main()
{
    A* a = new A();
    try
    {
        delete a;
    }
    catch(...)
    {
        cout << "eek" << endl;
    }
    return 0;
}

输出:

hi
eek

实时演示

我看过:

但是我找不到针对析构函数中异常的确切发生的答案(1)(相对于构造函数)和(2)带有重载的删除操作。

But I couldn't find an answer to what exactly happens (1) for an exception in the destructor (as opposed to the constructor) and (2) with an overloaded delete.

我不需要关于在析构函数中引发异常的演讲,这是一种不好的做法-我只是遇到了类似的代码, 'm古玩

I don't need a lecture on throwing an exception in a destructor being bad practice - I just ran into similar code and I'm curious about the behaviour.

如果存在此类引用,我希望得到标准或类似引用所支持的答案。

I would prefer an answer supported by the standard or similar references, if such references exist.

推荐答案


标准草案N4296 5.3.5,第121页说:

The standard Draft N4296 5.3.5, pag 121 says:


[expr.delete] [注意:无论对象的析构函数还是数组的某些元素引发异常,都会调用释放函数

—尾注]

[expr.delete] [ Note: The deallocation function is called regardless of whether the destructor for the object or some element of the array throws an exception. — end note ]

因此操作符删除

但是,正如注释中出现的那样,某些编译器未正确调用 operator delete 。可以作为错误编译器解决。

However, as has emerged from the comments, some compilers does not properly call the operator delete. This can be resolved as bug compiler.

已针对以下漏洞进行了测试:

Bug tested for:


  • < a href = http://coliru.stacked-crooked.com/a/b89537fd1ed1164e rel = nofollow noreferrer> GCC 4.8

  • Visual Studio 2015

  • GCC 4.8
  • Visual Studio 2015

这篇关于当在析构函数中引发异常时,为什么不调用过载的删除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆