我知道Object *pObject=new Object
包含两个步骤:
并致电delete pObject
:
但是当新的Object进程,如果第2步抛出异常,如果运算符delete被系统调用来释放内存?
答案 0 :(得分:1)
不,不会调用析构函数。由于对象构造不正确,因此调用析构函数是不安全的。但是,如果任何成员对象已完全构造,则它们将被销毁(因为对象已完成)。
有些人建议不要抛弃构造函数,我相信它比僵尸状态更好,这类似于错误代码并且会产生冗长的代码。只要您遵循RAII,您应该没事(每个资源都由它自己的对象管理)。在你投入构造函数之前,请确保你清理了你已经完成了一半的任何事情,但是如果你使用的RAII应该是什么都没有。
以下输出“B”:
#include <iostream>
struct B {
~B() { std::cout << "B" << std::endl; }
};
struct A {
A() : b() { throw(1); }
~A() { std::cout << "A" << std::endl; }
B b;
};
int main() {
try {
A *a = new A;
delete a;
} catch(int a) {}
}
修改: 以上不是你问的,是的,调用了删除操作符,http://www.cplusplus.com/reference/new/operator%20delete []说:
“这些释放函数由delete-expressions和new-expression调用,用于在破坏(或无法构造)具有动态存储持续时间的对象后释放内存。”
可以通过覆盖运算符delete
来测试。
答案 1 :(得分:0)
是的,将调用operator delete来释放分配的内存。
以下程序可以证明:
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
A() { cout << "A() at " << this << endl; throw 1; }
~A() { cout << "~A() at " << this << endl; }
};
int main(int argc, char *argv[]) {
int N = 3;
for (int i = 0; i < N; ++i) {
try {
new A;
} catch (int a) {
// pass
}
}
return 0;
}
在我的系统上运行这个程序,我发现打印出的结果是这样的:
A() at 0x2170010
A() at 0x2170010
A() at 0x2170010
显然,析构函数不会被调用,因为没有
~A() at 0x2170010
打印出行。
肯定会调用operator delete,因为这三个对象的地址完全相同。