#include <iostream>
class Dude
{
public:
int age;
Dude(int age)
{
this->age = age;
}
};
int main(int argc, char* argv[])
{
Dude *dude1 = new Dude(21);
std::cout << dude1->age << '\n';
delete dude1;
return 0;
}
这是释放dude1
内存并销毁对象dude1
的正确方法吗?
如果作为默认析构函数,析构函数将执行哪些内存释放和清除操作?dude1->~Dude();
这段代码是做什么的?
1条答案
按热度按时间vq8itlhq1#
这是释放
dude1
内存并销毁对象dude1
的正确方法吗?是的,从技术上讲是正确的。
但是,这并不是最好的选择。一个更好的选择是在自动存储中创建
Dude
对象,而不用担心它的释放/清理,让编译器为你担心,例如:如果你必须动态创建对象,至少使用一个像
std::unique_ptr
这样的智能指针,这样你就不需要手动delete
对象,例如:如果作为默认析构函数,析构函数将执行哪些内存释放和清除操作?
在这个例子中,什么都没有。
一般来说,当你处理对象时,在 * 分配/解除分配 * 和 * 创建/销毁 * 之间有一个明确的职责分离。首先为对象保留内存,然后在该内存中创建对象。随后,首先销毁对象,然后释放其内存。
当一个对象具有 * 自动存储持续时间 * 时,它的内存被保留在调用作用域(例如,函数/块中的局部变量,类的数据成员等),并且它在该作用域的内存中被创建。当该作用域结束时(例如,函数/块结束,包含的对象被销毁等),作用域对象被自动销毁,并且它的内存被释放。
因此,在您的示例中,
Dude
的默认 * 析构函数 * 什么也不做,因为它没有要销毁的东西。Dude
有一个int
数据成员,该成员是在Dude
内使用 * 自动存储持续时间 * 创建的。创建Dude
对象时,int
的空间将包含在Dude
对象的内存分配中,但是在Dude
对象在该存储器中被构造之前,int
对于使用是无效的。稍后,当Dude
对象被销毁时,当调用Dude
对象的析构函数时,int
变为无效,然后当释放Dude
对象的内存时,int
的内存消失。在我上面的第一个例子中,
Dude
对象具有 * 自动存储持续时间 *,它的作用域是main()
,因此编译器在main()
的堆栈帧内保留内存来保存Dude
对象,然后创建Dude
对象当main()
退出时,Dude
对象超出作用域并被销毁(即调用其析构函数),当堆栈帧被清除时,其内存被释放。在我上面的第二个示例中,
Dude
对象具有 * 动态存储持续时间 *。它的作用域是动态内存。new
分配动态内存来保存Dude
对象,然后创建Dude
对象(即调用其构造函数)。稍后,delete
销毁Dude
对象(即调用其析构函数)并释放new
已分配的动态内存。注意
Dude
里面的int
总是有 * automatic storage duration *,它的作用域是Dude
,所以它在Dude
对象被分配时被分配,在Dude
对象被释放时被释放,不管是在自动内存(即栈)还是在动态内存(即堆)中。dude1->~Dude();
这段代码是做什么的?
它显式调用对象的析构函数,就像其他方法调用一样。但是,不要这样做,除非对象是用
placement-new
构造的,例如: