我看到一些代码可以执行以下操作:
ExampleObject< T > * eo = const_cast< ExampleObject< T > * >(this);
eo->~ExampleObject();
free( eo );
有问题的ExampleObject已使用new布局分配。 没有提供用户定义的析构函数,所以我认为这是编译器提供的默认析构函数。
我不明白为什么有必要在这里调用析构函数。如果我们有一个用户定义的析构函数,它为某些类成员解除了内存分配,那么我可以理解这里的用法,但是对于默认的析构函数,我不知道为什么要这么做。
对象的默认析构函数做什么,需要我们在释放对象的已分配内存之前调用它?
答案 0 :(得分:4)
对象的默认析构函数做什么
它调用对象的数据成员的析构函数(如果有的话)。
那将要求我们在释放对象分配的内存之前调用它?
只有在已经存在的内存块中使用placement-new
构造对象时,析构函数才应该被明确调用。使用placement-new
可以将对象构造/销毁与内存分配/解除分配的任务分开,因此您需要显式构造和销毁对象,但是不必分配/取消分配其内存块,但是您可以对其进行管理你想在其他地方。
如果您不使用placement-new
来构造对象,而是使用new
来分配+构造对象,则必须使用delete
来破坏+释放对象(并且应该最好使用智能指针std:unique_ptr
或std::shared_ptr
来为您处理)。
如果您不使用任何形式的new
构造对象,则不要尝试完全手动破坏该对象。该对象位于自动存储中,编译器将为您管理该对象。
答案 1 :(得分:1)
C分配函数对C ++对象一无所知。与new
和delete
分配所需的内存并调用构造函数/析构函数不同,C函数所做的全部工作就是分配/释放适当大小的可用内存。
因此,当您使用C函数时,必须调用分配函数来获取内存,在其上调用new放置以在内存中实际构造对象(实际上必须具有该类型的对象)。然后,完成操作后,您需要通过手动调用析构函数来销毁对象(您需要执行此操作以使对象的生存期正确结束),然后将指针传递给free以便释放内存。
这就是为什么您不应该在C ++中使用*alloc
和free
的原因。它们需要大量的额外工作,而且类型安全。
答案 2 :(得分:0)
当对象超出范围时,将自动调用默认的析构函数:
默认析构函数始终调用其成员对象的析构函数(不适用于指向对象的成员变量)。如果我们动态分配内存,则应由我们处理,否则默认析构函数将清除局部变量。
如果我们不在类中编写自己的析构函数,则编译器会为我们创建一个默认的析构函数。除非我们在类中动态分配了内存或指针,否则默认析构函数可以正常工作。 当一个类包含指向在该类中分配的内存的指针时,我们应该编写一个析构函数以释放该类实例之前的内存。必须这样做以避免内存泄漏。