C++学习笔记 14 析构函数的调用时机

析构函数的调用时机

  1. 栈对象在当前栈作用域被释放时自动被释放,且调用析构函数
  2. 堆对象需要手动delete,才能被释放,和调用析构函数
#include<iostream>

class Entity22 {
public:
	int x;
	Entity22() {
		std::cout << "Create Entity" << std::endl;
	}

	~Entity22() {
		std::cout << "Destroy Entity" << std::endl;
	}
};


int* CreateArray() {
	//变量在栈中创建,这样的写法是错误的❌️
	//int Arr[50];
	//堆变量可以return给外部
	int* Arr = new int[50];
	return Arr;
	//方法结束,方法栈被释放,方法栈中变量也被释放了,即便return也不能被外部调用,而堆中对象可以
}

void createObj() {
	//栈对象,在当前方法执行完成后,当前方法作用域栈自动被释放,包括此对象,且析构函数自动被执行
	Entity22* ent;
	//堆对象,在当前方法执行完成后,当前方法作用域栈自动被释放,但此对象不在栈中,在堆中,不被释放,析构函数不被执行
	//当手动delete堆对象的时候,才会释放堆中对象,其析构函数才会执行
	Entity22* entity = new Entity22();
	std::cin.get();
	delete entity;
}


//如果栈上的变量会自动消失,那他有什么用呢?有没有其他办法,让他用在好的方面?
//答案是有的。他在很多方面都非常有用,可以帮助我们自动化代码
//eg: 其中我们可以做的一件事是,比如说利用类的作用域来实现的,像是智能指针:smart_ptr,或是unique_ptr,这是一个作用域指针
//或者像作用域锁。。。。。。有很多例子
//最简单的例子就是作用域指针了,它的本质就是一个类,是一个指针的包装器,在构造时再堆上分配指针,然后析构时删除指针。
//我们可以自动化这个new和delete。


//这就是一个简单的作用域指针
class ScopePtr {
private:
	Entity22* m_Ptr;
public:
	ScopePtr(Entity22* ptr):m_Ptr(ptr) {}
	~ScopePtr() {
		delete m_Ptr;
	}
};

int main() {
	CreateArray();
	createObj();

	//e是分配在栈上的,当e被销毁时,调用析构函数,Entity22指针也会被销毁
	//这种可以自动构造、自动析构、离开作用域之后就自动销毁的栈变量是非常有用的
	{
		ScopePtr e(new Entity22());
	}
}
posted @ 2025-12-11 10:18  超轶绝尘  阅读(3)  评论(0)    收藏  举报