所以我有这个课程
class Obj{ //simple class with constructor + destructor
public:
Obj(){cout<<"Obj1 has been created"<<endl;}
~Obj(){cout<<"Obj1 has been destroyed"<<endl;}
};
Obj * buffer[10]; //buffer
int main(int argc, char *argv[])
{
Obj * c = new(&buffer[0]) Obj;
delete &buffer[0];
system("PAUSE");
return EXIT_SUCCESS;
}
这种使用展示位置的方法&#34; new&#34;一个有效的?因为当我尝试删除地址时,析构函数没有被调用。
但如果我使用这行代码,析构函数就会被调用
Obj * c = new(&buffer[0]) Obj;
delete c;
有人可以告诉我发生了什么吗?我真的必须删除指针来调出析构函数吗?
答案 0 :(得分:4)
在示例中使用placement new以及尝试销毁它都是无效的:
buffer
包含指向Obj
的指针。无法保证指针为对象提供足够的空间,或者指针正确对齐以保存对象的对象。ptr->~Obj()
的显式析构函数调用。正确使用展示位置可能是这样的:
Obj* objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// ...
objects[1]->~Obj();
delete[] buffers[1];
(显然,在实际代码中,您可以通过合适的RAII类来保护不同的缓冲区和对象,以避免资源泄漏。)
答案 1 :(得分:1)
使用placement new,您必须直接调用析构函数。
buffer[0].~Obj();
// or
c->~Obj();
您必须 NOT 调用对象上的删除,因为这会尝试释放内存。由于内存未分配新内存,因此未定义行为。
// delete &buffer[0]; Don't do this.