智能指针(二)之auto_ptr

智能指针通过对象管理指针,在构造对象时完成资源的分配及初始化,在析构对象时完成资源的清理及汕尾工作。

因此,可以得到一份简洁版的智能指针代码:

template<class T>
class AutoPtr
{
public:
	//构造函数,完成资源的初始化与分配
	AutoPtr(T* ptr = NULL)
		:_ptr(ptr)
	{}
	//析构函数,完成资源的清理及汕尾工作
	~AutoPtr()
	{
		if (NULL != _ptr)
		{
			delete _ptr;
			_ptr = NULL;
		}
	}
private:
	T* _ptr;
};
int main()
{
	AutoPtr<int> a1(new int(100));
	AutoPtr<int> a2(new int(200));
	AutoPtr<int> a3(a1);
	AutoPtr<int> a4;
	a4 = a1;
	system("pause");
	return 0;
}

a1与a3共同管理一块空间,a2与a4共同管理一块空间,看起来好像没什么问题。但当程序跑起来,出了函数作用域之后就会崩毁


由于没有实现赋值操作符的重载,拷贝构造函数,所以在创建对象时编译器会自动调用默认的拷贝构造和赋值运算符重载。而系统默认的是浅拷贝

a1与a3,a2与a4共同管理同一块空间,一旦出了函数作用域,a3会调用析构函数,delete掉所指向的空间;而当a1调用析构函数时,此时a1所指向的已经是一块非法内存(因为被a3 delete过了),因此当a1再次delete这块空间时,程序就会挂掉。

同样一块空间被delete了两次,所以最终程序会挂掉。

而auto_ptr是怎么解决这个问题的呢——管理权转移

	AutoPtr(AutoPtr& a)//拷贝构造
	{
		//转移管理权
		_ptr = a._ptr;
		a._ptr = NULL;
	}
	//赋值运算符重载
	AutoPtr &operator=(AutoPtr &a)
	{
		if (a._ptr != _ptr)
		{
			AutoPtr tmp(a);
			std::swap(_ptr,tmp._ptr);//析构函数去管理tmp
		}
		return *this;
	}
auto_ptr通过转移管理权,来保证在赋值与拷贝时仅管理一份指针,而防止同一块空间释放多次的问题
#include<iostream>
using namespace std;

template<class T>
class AutoPtr
{
public:
	//构造函数,完成资源的初始化与分配
	AutoPtr(T* ptr = NULL)
		:_ptr(ptr)
	{}
	//析构函数,完成资源的清理及汕尾工作
	~AutoPtr()
	{
		if (NULL != _ptr)
		{
			delete _ptr;
			_ptr = NULL;
		}
	}
	AutoPtr(AutoPtr& a)//拷贝构造
	{
		//转移管理权
		_ptr = a._ptr;
		a._ptr = NULL;
	}

	//赋值运算符重载
	AutoPtr &operator=(AutoPtr &a)
	{
		if (a._ptr != _ptr)
		{
			AutoPtr tmp(a);
			std::swap(_ptr,tmp._ptr);//析构函数去管理tmp
		}
		return *this;
	}

private:
	T* _ptr;
};

int main()
{
	AutoPtr<int> a1(new int(100));
	AutoPtr<int> a2(new int(200));
	AutoPtr<int> a3(a1);
	AutoPtr<int> a4;
	a4 = a1;
	system("pause");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值