我编写了以下代码,它重载了 new
和 delete
运算符并在析构函数中抛出异常。
当抛出异常时,为什么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
我看了:
- throwing exceptions out of a destructor
- How does C++ free the memory when a constructor throws an exception and a custom new is used
- 及其他
但我无法找到确切发生了什么的答案 (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/