C++ 为什么在释放分配给某个对象的内存之前调用该对象的默认析构函数?
我看到一些代码执行以下操作:C++ 为什么在释放分配给某个对象的内存之前调用该对象的默认析构函数?,c++,memory-management,C++,Memory Management,我看到一些代码执行以下操作: ExampleObject< T > * eo = const_cast< ExampleObject< T > * >(this); eo->~ExampleObject(); free( eo ); ExampleObject*eo=const\u cast(此项); eo->~ExampleObject(); 免费(eo); 正在讨论的ExampleObject已使用placement new分配。 没有提供用户定
ExampleObject< T > * eo = const_cast< ExampleObject< T > * >(this);
eo->~ExampleObject();
free( eo );
ExampleObject*eo=const\u cast*>(此项);
eo->~ExampleObject();
免费(eo);
正在讨论的ExampleObject已使用placement new分配。
没有提供用户定义的析构函数,所以我认为这里使用的是编译器提供的默认析构函数
我不明白为什么有必要在这里调用析构函数。如果我们有一个用户定义的析构函数,为它的一些类成员取消分配内存,我可以理解这里的用法,但是对于默认析构函数,我不知道为什么要这样做
一个对象的默认析构函数做什么,需要我们在释放为该对象分配的内存之前调用它?
对象的默认析构函数做什么
它为对象的数据成员调用析构函数(如果有)
这需要我们在释放为对象分配的内存之前调用它吗
唯一应该显式调用析构函数的时间是在预先存在的内存块中使用构造对象时。使用placement new
将对象构造/销毁任务与内存分配/释放任务分离,因此您需要显式构造和销毁对象,但不必分配/释放其内存块,您可以在其他地方以任何方式管理它
如果不使用placement new
构造对象,而是使用new
分配+构造对象,则必须使用delete
销毁+解除分配对象(最好使用智能指针,std:unique\u ptr
或std::shared\u ptr
,为您处理该问题)
如果不使用任何形式的< <代码> < <代码> >构造对象,则不要试图手动销毁对象。对象是自动存储的,编译器将为您管理。 < P>分配函数不了解C++对象。与<代码> > < <代码> >和>代码>删除<代码>分配内存NEE调用构造函数/析构函数时,C函数所做的全部工作就是分配/取消分配适当大小的内存,以便使用 因此,当您使用C函数时,您必须调用分配函数来获取内存,在其上调用placement new来实际在内存中构造对象(这是实际拥有该类型对象所必需的)。然后,当您使用完该函数后,您需要通过手动调用析构函数来销毁该对象(您需要这样做,以便对象的生存期正确结束),然后将指针传递到free,以便释放内存
这就是为什么你不应该在C++中使用<代码> * OLC/<代码>和<代码>免费>代码>。它们需要大量额外的工作而不是类型安全的。
< P>一个默认析构函数,当对象超出范围时,自动调用默认析构函数:当一个类包含一个指向类中分配的内存的指针时,我们应该编写一个析构函数,在类实例被销毁之前释放内存。必须这样做,以避免内存泄漏。当对象超出范围时,调用
dtor
。您不必手动调用其中任何一个。如果u使用placement new构造对象。不要使用此问题中的语法。这会使问题本身不清楚。很可能您看到:exampleObject->~ClassName()
,其中ClassName
是用于创建exampleObject
的类。只有在使用malloc
而不是new
分配内存,并使用placementnew
初始化时,您才会看到这一点。placement new确实用于构造对象,我将编辑问题以包括这一点--也许你可以写一个解释原因的答案?为了清楚起见,更新了代码示例。如果你使用了new和delete,你不需要显式调用dtor。@如果你使用了non-placementnew
,那么就可以了。如果你使用了placement new
,就不要使用delete