C++ 智能指针

发布时间 2023-08-20 16:37:36作者: OrzMiku

智能指针

使用智能指针需要引入 memory 头文件

unique_ptr

#include<iostream>
#include<string>
#include<memory>

class Entity {
public:
	Entity() {
		std::cout << "Created Entity!" << std::endl;
	}
	~Entity() {
		std::cout << "Destoryed Entity!" << std::endl;
	}
	void Print() {}
};

int main() {
	{
		// std::unique_ptr<Entity> entity(new Entity());
		// 下面是更安全的写法
		// (如果构造函数抛出异常,不会得到悬空指针造成内存泄漏)
		std::unique_ptr<Entity> entity = std::make_unique<Entity>();
		entity->Print();
	}
	return 0;
}

unique_ptr指针会在离开作用域的时候自动销毁,这就是一个智能指针。

但请注意,unique_ptr指针不能复制的。假如说e1复制了e0,当e0离开作用域被销毁时,e1就指向了一片被销毁的空间,就出问题了。事实上你也不能复制,编译器没法编译的。

如果真的想复制,就要使用到另一个智能指针了,往下看。

shared_ptr

shared_ptr和unique_ptr一样的,都是智能指针,不过shared_ptr可以复制。先说说他是怎么解决unique_ptr无法复制的问题的:引用次数法。

大部分情况下都是引用次数法,还是上面那个例子,e1复制了e0,此时有两个指针指向了一片空间,引用次数为2,当e0离开作用域被销毁了,让引用次数减1。没少一个引用就减1,当引用次数为0时才释放内存。

用法和unique_ptr很像,上代码:

#include<iostream>
#include<string>
#include<memory>

class Entity {
public:
	Entity() {
		std::cout << "Created Entity!" << std::endl;
	}
	~Entity() {
		std::cout << "Destoryed Entity!" << std::endl;
	}
	void Print() {}
};

int main() {
	{
		std::shared_ptr<Entity> e0;
		{
			std::shared_ptr<Entity> sharedEntity = std::make_shared<Entity>();
			e0 = sharedEntity; // 可以复制
		} // 出了这个作用域,sharedEntity没了,但是还有e0,所以没析构
	}// 这里e0也没了,在这里调用了析构函数
	return 0;
}

weak_ptr

弱指针,可以和shared_ptr一起使用。当一个weak_ptr复制一个shared_ptr时,不会让shared_ptr的引用次数增加。他只在乎他要复制的那个指针是否有效,但是不去维持这个指针一直有效。上代码:

#include<iostream>
#include<string>
#include<memory>

class Entity {
public:
	Entity() {
		std::cout << "Created Entity!" << std::endl;
	}
	~Entity() {
		std::cout << "Destoryed Entity!" << std::endl;
	}
	void Print() {}
};

int main() {
	{
		std::weak_ptr<Entity> e0;
		{
			std::shared_ptr<Entity> sharedEntity = std::make_shared<Entity>();
			e0 = sharedEntity; // 可以复制
		} // 出了这个作用域,sharedEntity没了,weak_ptr e0没有增加引用次数,所以这里就析构了
	}
	return 0;
}