在引发异常的构造后调用delete 我正在阅读有效的C++第三版,ITEM52“写布局删除,如果你写新的位置”。

在引发异常的构造后调用delete 我正在阅读有效的C++第三版,ITEM52“写布局删除,如果你写新的位置”。,c++,exception,constructor,new-operator,delete-operator,C++,Exception,Constructor,New Operator,Delete Operator,我想知道如何使运算符delete在构造抛出异常后自动调用 #include <iostream> using namespace std; class A { int i; public: static void* operator new(std::size_t size) throw(std::bad_alloc) { return malloc(size); } static void operator delete(void*

我想知道如何使运算符delete在构造抛出异常后自动调用

#include <iostream>
using namespace std;

class A {
    int i;
public:
    static void* operator new(std::size_t size) throw(std::bad_alloc) {
        return malloc(size);
    }
    static void operator delete(void* p) throw() {
        cout << "delete" << endl;
        free(p);
    }
    A() {
        throw exception();
    }
};

int main() {
    A* a = new A;
}
参考:

我应该在
try{}
中编写
new
。目前对例外情况知之甚少

#include <iostream>
using namespace std;

class A {
    int i;
public:
    static void* operator new(std::size_t size) throw(std::bad_alloc) {
        return malloc(size);
    }
    static void operator delete(void* p) throw() {
        cout << "delete" << endl;
        free(p);
    }
    A() {
        throw exception();
    }
};

int main() {
    try {
        A* a = new A;
    } catch (const exception&) {

    }
}

如果无法分配内存,则无法释放它。如果构造函数抛出,则会自动调用Delete。顺便说一下,这个例子实际上并不是placement new,placement delete不能直接调用。但是如果它是新放置的,构造函数抛出异常,那就是编译器将调用的删除位置,因此在您的书中给出建议。或者,总之,一个未被取消的异常与在顶层C++中捕获的异常不同。实际上,我不知道为什么只有当
new
try{}
中时才会调用delete?未捕获的异常会终止程序,不会发生堆栈展开。捕获的异常会导致堆栈展开,这是清理内存的地方。标准说明“如果未找到匹配的处理程序,则调用函数
std::terminate()
;在调用
std::terminate()
之前是否展开堆栈是由实现定义的”。因此,编译器可以选择先删除
A
,然后再查找
catch
,或者推迟任何删除,直到捕捉到异常为止。如果它从未被抓住。。。
#include <iostream>
using namespace std;

class A {
    int i;
public:
    static void* operator new(std::size_t size) throw(std::bad_alloc) {
        return malloc(size);
    }
    static void operator delete(void* p) throw() {
        cout << "delete" << endl;
        free(p);
    }
    A() {
        throw exception();
    }
};

int main() {
    try {
        A* a = new A;
    } catch (const exception&) {

    }
}
delete