为什么要在释放分配给该对象的内存之前调用该对象的默认析构函数?

时间:2019-06-21 20:44:46

标签: c++ memory-management

我看到一些代码可以执行以下操作:

ExampleObject< T > * eo = const_cast< ExampleObject< T > * >(this);
eo->~ExampleObject();
free( eo );

有问题的ExampleObject已使用new布局分配。 没有提供用户定义的析构函数,所以我认为这是编译器提供的默认析构函数。

我不明白为什么有必要在这里调用析构函数。如果我们有一个用户定义的析构函数,它为某些类成员解除了内存分配,那么我可以理解这里的用法,但是对于默认的析构函数,我不知道为什么要这么做。

对象的默认析构函数做什么,需要我们在释放对象的已分配内存之前调用它?

3 个答案:

答案 0 :(得分:4)

  

对象的默认析构函数做什么

它调用对象的数据成员的析构函数(如果有的话)。

  

那将要求我们在释放对象分配的内存之前调用它?

只有在已经存在的内存块中使用placement-new构造对象时,析构函数才应该被明确调用。使用placement-new可以将对象构造/销毁与内存分配/解除分配的任务分开,因此您需要显式构造和销毁对象,但是不必分配/取消分配其内存块,但是您可以对其进行管理你想在其他地方。

如果您不使用placement-new来构造对象,而是使用new来分配+构造对象,则必须使用delete来破坏+释放对象(并且应该最好使用智能指针std:unique_ptrstd::shared_ptr来为您处理)。

如果您不使用任何形式的new构造对象,则不要尝试完全手动破坏该对象。该对象位于自动存储中,编译器将为您管理该对象。

答案 1 :(得分:1)

C分配函数对C ++对象一无所知。与newdelete分配所需的内存并调用构造函数/析构函数不同,C函数所做的全部工作就是分配/释放适当大小的可用内存。

因此,当您使用C函数时,必须调用分配函数来获取内存,在其上调用new放置以在内存中实际构造对象(实际上必须具有该类型的对象)。然后,完成操作后,您需要通过手动调用析构函数来销毁对象(您需要执行此操作以使对象的生存期正确结束),然后将指针传递给free以便释放内存。

这就是为什么您不应该在C ++中使用*allocfree的原因。它们需要大量的额外工作,而且类型安全。

答案 2 :(得分:0)

当对象超出范围时,将自动调用默认的析构函数:

  1. 函数结束
  2. 程序结束
  3. 包含局部变量的块结束
  4. 删除操作符称为

默认析构函数始终调用其成员对象的析构函数(不适用于指向对象的成员变量)。如果我们动态分配内存,则应由我们处理,否则默认析构函数将清除局部变量。

如果我们不在类中编写自己的析构函数,则编译器会为我们创建一个默认的析构函数。除非我们在类中动态分配了内存或指针,否则默认析构函数可以正常工作。 当一个类包含指向在该类中分配的内存的指针时,我们应该编写一个析构函数以释放该类实例之前的内存。必须这样做以避免内存泄漏。