C++ -- 智能指针 auto_ptr,unique_ptr,shared_ptr的简单实现和原理

一,为什么需要智能指针

智能指针是一种预防型的内存泄漏的解决方案。由于C++没有垃圾回收器机制,所以每次new出来的资源都需要手动的delete,如果没有手动释放,就会造成资源泄漏等问题。因此,为了避免这一问题,C++引入了智能指针,可以较好的解决异常安全等带来的内存泄漏问题。

智能指针的原理:RAII(自动释放资源)+具有指针类似的行为operator*() / operator->()+解决浅拷贝的方式。
所有不同类型的智能指针都包括以下这些内容:
1,RAII:资源可以自动释放
2,具有指针类似的行为:operator*()/operator->()
3,都需要考虑解决浅拷贝的问题

二,RAII
RAII–资源获取时就初始化,将内存的管理交付给了对象,在构造函数中申请资源,在析构函数中释放资源。这样就避免了资源泄漏问题。

简单模拟实现:

template<class T>
class smartptr
{
public:
	smartptr(T* ptr = nullptr)
		:_ptr(ptr)
	{
		cout << "smartptr(T* )" << endl;
	}
	~smartptr()
	{
		cout << "~smartptr(T* )" << endl;
		if (_ptr)
		{
			delete _ptr;
			_ptr = nullptr;
		}
	}
private:
	T* _ptr;
};
void testsmartptr()
{
	smartptr<int> sp(new int);
}
int main()
{
	testsmartptr();
	return 0;
}

RAII的作用:用户不用考虑什么时候释放资源,把释放资源的事情交给了编译器

但这样的简单实现会导致浅拷贝,导致一份资源多次释放

template<class T>
class smartptr
{
public:
	smartptr(T* ptr = nullptr)
		:_ptr(ptr)
	{
		cout << "smartptr(T* )" << endl;
	}
	~smartptr()
	{
		cout << "~smartptr(T* )" << endl;
		if (_ptr)
		{
			delete _ptr;
			_ptr = nullptr;
		}
	}
	T& operator*()
	{
		return *_ptr;
	}
	T* operator->()
	{
		return _ptr;
	}
private:
	T* _ptr;
};
void testsmartptr()
{
	int a = 10;
	int *pa = &a;
	int *pb(pa);
	smartptr<int> sp1(new int);
	smartptr<int> sp2(sp1);//由于没有拷贝构造函数,所以编译器会调用构造函数。sp1和sp2会指向同一块内存空间
}//在函数结束时,sp1,sp2都会释放内存,这是就会导致同一内存多次释放。
int main()
{
	testsmartptr();
	return 0;
}

虽然之前我们所遇到的string类也存在浅拷贝问题,它可以通过深拷贝来解决问题,但是我们这个智能指针却不能通过深拷贝的方式来解决。这是因为string所申请的空间是在类中申请的空间,所以在拷贝构造函数中也只需要在类中为新对象申请一块空间。但是我们所提供的智能指针,它的资源是用户提供的,并不是类自己申请。它没有自己申请的权利,只有释放的权利。因此它不能通过深拷贝的方式进行解决。

三,智能指针的类型

auto_ptr(C++98)

namespace heqing
{
	//auto_ptr解决的原理就是资源的转移
	template<class T>
	class auto_ptr
	{
	public:
		//RAII
		auto_ptr(T* 
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值