浅析智能指针(一)

一.什么是智能指针

       所谓智能指针就是智能/自动化的管理指针所指向的动态资源的释放。实际上智能指针是一种抽象数据类型,行为表现的像一个指针。通过重载“->”和“*”,就可以像使用指针一样来使用智能指针;而智能指针又是如何来管理指针指向对象的释放问题呢?其实这是RAII的一种应用。RAII(Resource acquisition is initialization),即资源分配即初始化。定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放 。那么有了指针我们为什么还需要智能指针呢?接下来看下边的例子。

#include <iostream>
#include <string>
using namespace std;

void Fun()
{
	string* p1 = new string("hello");
	bool IsEnd = true;

	if (IsEnd)
	{
		throw 1;
		delete p1;
	}
	delete p1;
}

int main()
{
	try
	{
		Fun();
	}
	catch (int e)
	{
		cout << e << endl;
	}
	return 0;
}

这段代码看起来好像没什么问题,但其实隐藏了一个非常重要的错误--内存泄漏。但是从哪泄漏的呢?那就要从抛出异常说起了,在上述代码中,异常被抛出后,是在main函数中捕获的,但是Fun函数中的p1并没有被释放,所以造成内存泄漏。所以,这时候就需要智能指针,能够自动的帮我们释放空间。

二、智能指针的发展

智能指针的发展可以简单的分为三个阶段:

(1)auto_ptr    c++98/03 

(2)scoped_ptr/shared_ptr/week_ptr    boost

(3)unique_ptr/shared_ptr/week_ptr   c++11

auto_ptr 的本质是管理权的转移,带有缺陷的设计,一般不建议使用。scope_ptr/unique_ptr是防拷贝,功能不全。shared_ptr是通过引用计数来解决空间释放问题,功能强大,但是有时候会存在循环引用的问题,这时候就需要配合week_ptr来解决这个问题


首先来说说aotu_ptr,我们先看下边一段代码:

template<typename T>
class AutoPtr
{
public:
	AutoPtr(T* ptr = NULL)
		:_ptr(ptr)
	{}

	AutoPtr(AutoPtr<T>& ap)//管理权的转移
	{
		this->_ptr = ap._ptr;
		ap._ptr = NULL;
	}

	//s2=s1,先将s2释放掉,再将s1赋给s2,将s1置空
	AutoPtr<T>& operator=(AutoPtr<T>& ap)
	{
		if (this != &ap)
		{
			delete this->_ptr;
			this->_ptr = ap._ptr;
			ap._ptr = NULL;
		}
		return *this;
	}

	T& operator*()//   *的重载
	{
		return *_ptr;
	}

	T& operator->()//  ->的重载
	{
		return _ptr;
	}

    ~AutoPtr()
    {
		delete _ptr;
    }

	void Reset(T* ptr = NULL)//赋空
	{
		if (_ptr != ptr)
		{
			delete _ptr;
		}
		_ptr = ptr;
	}

protected:
	T* _ptr;
};

对于内置类型来说,两个指针是可以同时指向同一块空间的,并且通过这个指针对该空间进行操作是不会出现问题。但在自定义类型中,两个指针指向同一块空间会产生问题。管理权的转移就是一种解决办法。在拷贝构造和运算符重载的时候会发生管理权的转移,我们的目的是通过拷贝构造,让两个智能指针管理同一个对象。如果用默认的拷贝构造函数就会产生浅拷贝问题,两个指针指向同一个对象在进行析构的时候,这块空间会被释放两次,就会出现内存错误。所以,一个简单的办法,就是让原来的那个指针放弃对该空间的操作权限,所以实际上只有一个指针起作用。同时,这也是auto_ptrd的一个缺陷。
管理权转移的步骤如下:












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值