C++初探智能指针

什么是智能指针

学过C语言的人肯定对“指针”这个概念不陌生,简单来说,指针就是“地址”。
那么智能指针是什么呢?“智能地址”吗?
准确地来说,智能指针并不能算作是指针。在《C++ Primer Plus》一书中,就这样定义到:

智能指针是行为类似于指针的类对象,但这种对象还有其他功能

可以看到,智能指针其实是一个类对象

为啥需要智能指针

那既然已经有了指针,为什么需要智能指针呢?智能指针智能在哪里呢?
我们首先来看下面这个问题:

void remodel(std::string& str)
{
	std::string * ps = new std::string(str);
	...
	str = *ps;
	return;
}

我们会发现,每当调用的时候,该函数都会分配堆中的内存,但是从来不收回,从而导致内存泄漏
对此问题,我们最先想到的解决方法就是在retrun前面添加下面的语句,来释放分配的内存:

delete ps;

然而,但凡涉及到“别忘了”的解决方法,很少是最佳的。
因为我们很可能会忘记掉;
有时候可能记住了,但也有可能在不经意间删除或者注释掉了这些代码;
即使确实没有忘记,也可能有问题,请看如下变体:

void remodel(std::string& str)
{
	std::string* ps = new std::string(str);
	...
	if(weird_thing())
		throw exception();
	str = *ps;
	delete ps;
	return;
}

当出现异常exception时,delete将不被执行,因此也将导致内存泄漏。
那么如何解决这个问题呢?
答案就是智能指针了!!!

智能指针的原理

智能指针是一个类对象,这个类的构造函数中传入了一个指针,析构函数中释放传入的指针。
由于该类对象是在栈上开辟和释放的,所以,当我们的函数(或程序)结束时就会被自动释放

简单来说,智能指针就是利用了在函数(程序)开始时系统自动分配,结束时系统自动释放的特性,将在堆上指向开辟内存的函数指针封装在类对象的构造函数中,将指向释放内存的函数指针封装在类对象的析构函数中。
这样,内存的开辟和释放均由系统来操作,不需要人工操作,达到了智能的目的。

智能指针的类别

智能指针有多种,尤其是C11标准之后,又对智能指针作了进一步的补充。
我们在这里,先来看看最简单的三种智能指针:

  • auto_ptr
  • unique_ptr
  • shared_ptr

注意:
其中的auto_ptrC++98 所提供的解决方案;C++11已经将其摒弃,并提供了另外两种解决方案。

简单案例

首先,我们需要知道,要创建智能指针对象,必须包含头文件#include <memory>,该文件模板定义。然后使用通常的模板语法来实例化所需类型的指针。
如下程序演示了如何使用三种智能指针:

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

class Report
{
private:
	std::string str;
public:
	Report(const std::string s) :str(s)
	{
		std::cout << "Object created!\n";
	}
	~Report() { std::cout << "Object deleted!\n"; }
	void comment()const
	{
		std::cout << str << "\n";
	}
};

int main()
{
	{
		std::auto_ptr<Report> ps(new Report("using auto_ptr"));
		ps->comment();
	}
	{
		std::shared_ptr<Report> ps(new Report("using shared_ptr"));
		ps->comment();
	}
	{
		std::unique_ptr<Report> ps(new Report("using unique_ptr"));
		ps->comment();
	}

	return 0;
}

每个智能指针都放在一个代码块内,这样离开代码块时,指针将过期。

运行结果

如下是运行结果:
在这里插入图片描述
可以看到,程序运行时,对象自己就会析构掉,灰常的智能

参考资料

【1】Stephen Prata. C++ Primer Plus(第六版)中文版. 北京:人民邮电出版社. 2020.1:35.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值