天天看点

C++中shared_ptr与unique_ptr简单使用一,shared_ptr二,unique_ptr

为了免除new与delete带来的各种烦恼,C++11引入了更加好用更加健壮的智能指针供我们使用。

一,shared_ptr

为T类型的变量定义std::shared_ptr<T>共享指针

shared_ptr内部维护了资源引用数量的计数器。当不再有shared_ptr指向资源时,资源将自动被析构。默认调用delete函数。

使用资源时直接对共享指针 * 运算符解引用即可。

#include<cstdio>
#include<memory>

int main()
{
	std::shared_ptr<int> sp(new int(10));
	std::shared_ptr<int> sp2 = sp;
	printf("Shared_ptr=%p, Count=%d\n", sp.get(), sp.use_count());
	printf("Shared_ptr=%p, Count=%d\n", sp2.get(), sp2.use_count());
	sp.reset(); //sp取消引用
	printf("Shared_ptr=%p, Count=%d\n", sp2.get(), sp2.use_count());
	getchar();
	return 0;
}
           

运行结果:

Shared_ptr=00BA7AD8, Count=2

Shared_ptr=00BA7AD8, Count=2

Shared_ptr=00BA7AD8, Count=1

二,unique_ptr

unique_ptr实现的是以前auto_ptr类似的功能。

与shared_ptr可以使用多个指针引用资源不同的是,unique_ptr意味着资源最多只能由一个指针进行引用。用另外一个unique_ptr指针取代先前的指针时,先前的指针将被强制修改为nullptr,对该指针解引用将导致程序异常。

这时必须注意unique_ptr的赋值只能接受右值引用,否则编译报错。可以使用std::move()将左值转换为右值引用。

可以使用调用delete的默认std::unique_ptr<T>构造,也可以使用std::unique_ptr<T, class Delete>调用自己的释放资源的函数。

示例程序使用了后者,实现文件在各种不同情况下都能够正确关闭,避免了多次或者忘记了调用fclose()。

#include<cstdio>
#include<fstream>
#include<memory>

void close_file(std::FILE *fp) {
	std::fclose(fp);
	printf("File closed.\n");
}

int main()
{
	//std::auto_ptr<int> ap(new int(11));
	//printf("Auto_ptr=%X\n", ap);
	//std::auto_ptr<int> nap=ap;
	//printf("Old_Auto_ptr=%X\n", ap); //指向的内容被抢夺了
	
	std::ofstream("test.txt") << "!";

	{
		std::unique_ptr<FILE, decltype(&close_file)> fp(std::fopen("test.txt", "r"), &close_file);
		auto fp2 = std::move(fp);
		//auto fp3 = fp; unique_ptr赋值运算符支持右值引用,不能使用左值
		printf("Old_one=%p, New_one=%p\n", fp.get(), fp2.get());
		if (fp2) {
			printf("Get '%c'.\n", fgetc(fp2.get()));
		}
	}
	getchar();
	return 0;
}
           

运行结果:

Old_one=00000000, New_one=00BE78A8

Get '!'.

File closed.

可以看到,在退出了fp的作用域之后,文件被自动关闭了。

本来打算写auto_ptr和shared_ptr相关的,结果到cppReference上一看,auto_ptr已经被废弃使用了,C++17中甚至取消了对它的支持。不过C++给我的感觉是越来越臃肿,泛型比不过专业的面向对象语言,开源库也不如其他语言丰富。虽然仍然最喜欢使用C++写东西,但是以后C++还能维持它所处的地位吗?