我只是想知道这三种调用析构函数的方法是否有任何显着/严重的区别。考虑以下代码。请同时考虑 main()
中提到的两种情况。
class Sample
{
public:
~Sample()
{
cout << "destructor called" << endl;
}
void destroyApproach1() { this->~Sample(); }
void destroyApproach2() { delete this; }
};
void destroyApproach3(Sample *_this)
{
delete _this;
}
void TestUsingNew()
{
Sample *pSample[] = { new Sample(), new Sample(),new Sample()};
pSample[0]->destroyApproach1();
pSample[1]->destroyApproach2();
destroyApproach3(pSample[2]);
}
void TestUsingPlacementNew()
{
void *buf1 = std::malloc(sizeof(Sample));
void *buf2 = std::malloc(sizeof(Sample));
void *buf3 = std::malloc(sizeof(Sample));
Sample *pSample[3] = { new (buf1) Sample(), new (buf2) Sample(), new (buf3) Sample()};
pSample[0]->destroyApproach1();
pSample[1]->destroyApproach2();
destroyApproach3(pSample[2]);
}
int main()
{
//Case 1 : when using new
TestUsingNew();
//Case 2 : when using placement new
TestUsingPlacementNew();
return 0;
}
请在回复时具体说明您正在回答哪个案例:案例 1 或案例 2,或两者兼而有之!
此外,我试图以这种方式编写 TestUsingPlacementNew()
,但它抛出了运行时异常 (MSVC++2008)。我不明白为什么:
void TestUsingPlacementNew()
{
const int size = sizeof(Sample);
char *buffer = (char*)std::malloc( size * 3);
Sample *pSample[] = { new (buffer) Sample(), new (&buffer[size]) Sample(),new (&buffer[2*size]) Sample()};
pSample[0]->destroyApproach1();
pSample[1]->destroyApproach2();
destroyApproach3(pSample[2]);
}
也许,内存填充和/或对齐可能是原因?
相关主题:Destructor not called after destroying object placement-new'ed
最佳答案
是的,这些方法之间存在巨大差异:
在
destroyApproach1
中,你只调用对象的析构函数;您实际上并没有释放它占用的内存。在
destroyApproach2
和destroyApproach3
中调用对象的析构函数并释放对象占用的内存(通过使用delete
表达式)。在第一个TestUsingPlacementNew
测试中,这两个也是错误的,因为对象占用的内存最初是通过调用malloc
分配的,而不是new
。
上次测试中出现运行时错误是因为您试图删除
数组中索引1
处的对象;指向该元素的指针最初不是通过调用 new
获得的。在第一个示例中,它仅“有效”(其中“有效”的真正意思是“行为未定义,但它似乎仍能正常运行”)因为所有三个指针都指向独立的堆分配。
关于c++ - 调用析构函数方法比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4426303/