c++ - 为什么在析构函数中抛出异常时不调用重载删除?

标签 c++ c++11 exception destructor delete-operator

我编写了以下代码,它重载了 newdelete 运算符并在析构函数中抛出异常。

当抛出异常时,为什么delete操作符中的代码没有执行(并打印出“bye”)?

如果不应该执行,(如何)释放内存?是one of the other delete operators叫什么?重载其中之一会导致执行相应的代码吗?还是内 stub 本没有被释放,因为破坏失败意味着它可能不应该被释放?

#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

Live demo .

我看了:

但我无法找到确切发生了什么的答案 (1) 析构函数中的异常(与构造函数相反)和 (2) 重载删除。

我不需要关于在析构函数中抛出异常的坏做法的讲座 - 我只是遇到了类似的代码,我对这种行为感到好奇。


我希望得到标准或类似引用文献支持的答案(如果存在此类引用文献)。

最佳答案

standard Draft N4296 5.3.5,第 121 页说:

[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

但是,从评论中可以看出,一些编译器没有正确调用operator delete。这可以作为错误编译器解决。

错误测试:

关于c++ - 为什么在析构函数中抛出异常时不调用重载删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52388238/

相关文章:

c++ - operator->返回的指针的有效性

c++ - 哈希函数说明

c++ - system() 使用 C++ 在 Window 7 上调用 .exe [权限问题]

c++ - 对不同的参数使用工厂方法模式

c++ - 如何保证准确的线程休眠间隔?

c++ - C++ STL 容器的空间复杂度

c++ - std::lock_guard 和 std::adopt_lock 行为无需锁定互斥体

java - 组织.hibernate.MappingException : <mapping> element in configuration specifies no known attributes

java - 如何从控制台获取异常日志并将其写入外部文件?

c# - 使用 log4net 将异常记录到数据库