智能指针shared_ptr实现

C++11提供了智能指针用于动态管理堆空间的内存分配与释放,通过维护智能指针这个栈对象使得当智能指针离开作用域时能够自动释放其管理的内存。
其中,最常用的应该是shared_ptr, 提供了共享语义,也即多个指针共享同一个资源。
实现原理维护一个指向资源的裸指针以及引用计数指针(都属于堆空间)。当智能指针离开作用域时,引用计数-1,当新生成一个智能指针时,引用计数+1,只有当引用计数=0时才会释放智能指针管理的内存空间。

下面来看下shared_ptr的实现细节吧。

#include <bits/stdc++.h>
using namespace std;

template <typename T>
class my_shared_ptr{
public:
	my_shared_ptr(T * t);
	~my_shared_ptr();
	my_shared_ptr(const my_shared_ptr<T> & origin);
	my_shared_ptr <T> & operator=(const my_shared_ptr<T> & origin);

public:
	T * get(){
		return row_ptr;
	}
	T operator *()
	{
		return * row_ptr;
	}
	T * operator ->()
	{
		return row_ptr;
	}
private:
	T * row_ptr = nullptr;
	int * count = nullptr;
};

template <typename T>
my_shared_ptr<T> :: my_shared_ptr(T * t)
{
 	row_ptr = t;
 	try{
 		count = new int(1);
 	}
 	catch(...)
 	{
 		delete row_ptr;
 		row_ptr = nullptr;
 		delete count;
 		count = nullptr;
 		cout << "Allocate memory for count fails" << endl;
 		exit(1);
 	}
 	cout << "constructer is called" << endl;
}

template<typename T>
my_shared_ptr<T> :: ~my_shared_ptr()
{
	if(--(*count)==0)
	{
		delete row_ptr;
		row_ptr = nullptr;
		delete count;
		count = nullptr;
		cout << "deconstructer is called" << endl;
	}
}
template<typename T>
my_shared_ptr<T> :: my_shared_ptr(const my_shared_ptr<T> & origin)
{
	row_ptr = origin.row_ptr;
	count = origin.count;
	(*count)++;
	cout << "copy constructer is called" << endl;
}
// first free then copy
template<typename T>
my_shared_ptr<T> & my_shared_ptr<T>::operator= (const my_shared_ptr<T> & origin)
{

	(*origin.count)++;

	if(--(*count)==0)
	{
		delete row_ptr;
		delete count;

	}

	row_ptr = origin.row_ptr;
	count = origin.count;
	cout << "Assignment operator overload is called" << endl;
	return *this;
} 

注意点:

  1. 拷贝赋值函数中需要先释放原有资源,为了避免自身赋值这种情况,先将(*origin)++;
  2. delete指针释放资源之后,需要将指针置为nullptr
  3. 只有指针参数的构造函数中,引用计数指针需要通过new分配内存,通过try_catch处理堆空间不足的异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值