C++:智能指针

智能指针的引入

void func(int* ptr)
{
	auto_ptr<int>p(new int);		
	if(ptr==NULL)
	{
		throw exception("ptr is null");//new 开辟了内存还没释放   抛出异常跳出了 就会产生内存泄露
												//使用智能指针后   如果再对异常进行处理 就不会产生内存泄露
	}
	*p=*ptr;
	//delete p;
}
int main()
{
	func(NULL);
}

运用智能指针解决因程序异常退出,导致无法释放申请的堆内存或者其他原因导致的内存泄漏问题。

什么是智能指针

使用普通指针,容易造成堆内存泄露(忘记释放或其他原因),二次释放,释放了野指针程序崩溃等问题等,而使用智能指针能更好的管理堆内存。

C++11以前boost标准库只存在一种智能指针auto_ptr,但因存在较多的缺陷,在C++11以后摒弃了auto_ptr,并提出了另外三种智能指针:unique_ptr 、 shared_ptr 、weak_ptr。使用它们需要包含头文件 #include < memory>

首先智能指针并不是一个指针智能指针是一个模板,由智能指针实例化出来的的对象具有和常规指针相似的行为,但是它能够自动的释放所指向的对象所以我们称之为智能指针

如果我们用普通指针来创建一个指向某个对象的指针,那么我们最后必须要手动释放这块空间,而智能指针它是一个类,它释放空间是通过析构函数完成的,正是由于有了这一层封装机制,所以智能指针才能够管理一个对象的生命周期

定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放。这样的方法称为RAII(Resource Acquisition is initialization)

对于编译器来说智能指针实际上是一个栈对象,并非指针类型,在栈对象生命期即将结束时,智能指针通过析构函数释放由它管理的堆内存

所以智能指针就是利用栈上的对象出作用域自动析构的特点,把资源释放的代码,放在智能指针的析构函数里面从而达到自动释放资源的目的

智能指针的设计原理和实现

自定义简单实现智能指针
// 自定义智能指针
template<typename T>
class CSmartPtr
{
public:
	// 构造函数
	CSmartPtr(T *ptr = nullptr)
		:mptr(ptr) {}
	~CSmartPtr()  { delete mptr; }

private:
	T *mptr;
};
int main()
{
	CSmartPtr<int> ptr(new int);
	return 0;
}

由于ptr是栈上的对象,不管是函数正常执行完,还是运行过程中出现异常,栈上的对象都会自动调用析构函数,在析构函数中进行了delete 操作,保证释放资源

CSmartPtr<int> ptr(new int);
CSmartPtr<int> ptr1(ptr);

分析上述代码,由于我们未给智能指针提供拷贝构造函数,那么第二条语句则调用的是默认构造函数进行浅拷贝操作,我们注意到,ptr 与 ptr1 都持有相同的资源,那么程序结束,ptr1先调用析构函数释放了资源,当接下来ptr调用析构函数时,将会delete野指针,程序会出现严重的错误

因此,智能指针就需要解决两个问题

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值