智能指针

强智能指针shared_ptr:

        把管理的内存块的地址和有多少个指针指向封装成一个结构体(引用计数管理器(数组)),放在一个单独的类中。

        接口:addRef()、delRef()、 getRef();

        只需有一个管理器存在即可:适合使用单例模式:创建静态成员(为了线程安全应在类外先进行创建)

        addRef():

               1、地址没有记录:添加结点,引用计数置为1

               2、地址已经记录:引用计数+1

       delRef():

             1、地址没有记录:抛出异常

             2、地址记录:减引用计数

普通模式: 

#include<iostream>
using namespace std;

class RefManage
{
public:
	RefManage():length(0){}
	void addRef(void* ptr)
	{
		if(ptr != NULL)
		{
			int index = find(ptr);
			if(index < 0)
			{
				arr[length].addr = ptr;
				arr[length++].refcount = 1;
			}
			else arr[index].refcount++;
		}
	}
	void delRef(void* ptr)
	{
		int index = find(ptr);
		if(index < 0)
		{
			throw exception("addr is not exist");
		}
		else
		{
			if(getRef(ptr) != 0)
			{
				arr[index].refcount--;
			}
			else
				throw exception("refcount is 0");
		}
	}
	int getRef(void* ptr)
	{
		if(ptr == NULL) return 0;
		int index = find(ptr);
		if(index < 0)
		{
			return -1;
		}
		else
		{
			return arr[index].refcount;
		}
	}
private:
	int find(void* ptr)
	{
		for(int i = 0;i < length;i++)
		{
			if(arr[i].addr == ptr)return i;
		}
		return -1;
	}
	class Node
	{
	public:
		Node(void* ptr = NULL,int ref = 0):addr(ptr),refcount(ref){}
	public:
		void* addr;
		int refcount;
	};
	Node arr[10];
	int length;//数组元素的有效长度  当前可以插入的数组下标
};

template<class T>
class Shared_ptr
{
public:
	Shared_ptr(T* ptr):mptr(ptr)
	{
		AddRef();
	}
	Shared_ptr(const Shared_ptr<T>& rhs):mptr(rhs.mptr)
	{
		AddRef();
	}
	Shared_ptr<T>& operator=(const Shared_ptr<T>& rhs)
	{
		if(this != &rhs)
		{
			DelRef();
			if(!GetRef())
			{
				delete mptr;
			}
			mptr = rhs.mptr;
			AddRef();
		}
		return *this;
	}
	~Shared_ptr()
	{
		DelRef();
		if(!GetRef())
		{
			delete mptr;
		}
		mptr = NULL;
	}
	T& operator*()
	{
		return *mptr;
	}
	T* operator->()
	{
		return mptr;
	}
private:
	void AddRef()
	{
		rm->addRef(mptr);
	}
	void DelRef()
	{
		rm->delRef(mptr);
	}
	int GetRef()
	{
		return rm->getRef(mptr);
	}
private:
	T* mptr;
	static RefManage* rm;
};

template<class T>
RefManage* Shared_ptr<T>::rm = new RefManage;

int main()
{
	int*p = new int;
	Shared_ptr<int> sp1(p);
	Shared_ptr<int> sp2(p);
	Shared_ptr<int> sp3(p);
	Shared_ptr<int> sp4(p);

	return 0;
}

 线程安全的单例模式:

        

#include<iostream>
using namespace std;

class RefManage
{
public:
	static RefManage* getInstance()//通过此接口来创建对象,返回值不能直接用类类型,不然会生成临时对象
	{
		return &rm;//在main函数前就将对象生成好,在分线程时没有进程的创建,只需要返回已存在对象的地址,所以没有线程安全的问题
	}
private:
	static RefManage rm;//静态的成员对象属于类作用域下:优点:可以看到类中所有的东西(包括私有的),相当于把对象的生成放再类中;
	//一定要在类外初始化,而对象生成就在初始化的时候,因为是全局变量,所以是放在.data段,
private:
	RefManage():length(0){}//屏蔽构造函数和拷贝构造函数
	RefManage(const RefManage& rhs);//用不上,所以只要声明,不用实现;原因:只有一个对象,不可能再去拷贝
public:	
	void addRef(void* ptr)
	{
		if(ptr != NULL)
		{
			int index = find(ptr);
			if(index < 0)
			{
				arr[length].addr = ptr;
				arr[length++].refcount = 1;
			}
			else arr[index].refcount++;
		}
	}
	void delRef(void* ptr)
	{
		int index = find(ptr);
		if(index < 0)
		{
			throw exception("addr is not exist");
		}
		else
		{
			if(getRef(ptr) != 0)
			{
				arr[index].refcount--;
			}
			else
				throw exception("refcount is 0");
		}
	}
	int getRef(void* ptr)
	{
		if(ptr == NULL) return 0;
		int index = find(ptr);
		if(index < 0)
		{
			return -1;
		}
		else
		{
			return arr[index].refcount;
		}
	}
private:
	int find(void* ptr)
	{
		for(int i = 0;i < length;i++)
		{
			if(arr[i].addr == ptr)return i;
		}
		return -1;
	}
	class Node
	{
	public:
		Node(void* ptr = NULL,int ref = 0):addr(ptr),refcount(ref){}
	public:
		void* addr;
		int refcount;
	};
	Node arr[10];
	int length;//数组元素的有效长度  当前可以插入的数组下标
};

RefManage RefManage::rm;

template<class T>
class Shared_ptr
{
public:
	Shared_ptr(T* ptr):mptr(ptr)
	{
		AddRef();
	}
	Shared_ptr(const Shared_ptr<T>& rhs):mptr(rhs.mptr)
	{
		AddRef();
	}
	Shared_ptr<T>& operator=(const Shared_ptr<T>& rhs)
	{
		if(this != &rhs)
		{
			DelRef();
			if(!GetRef())
			{
				delete mptr;
			}
			mptr = rhs.mptr;
			AddRef();
		}
		return *this;
	}
	~Shared_ptr()
	{
		DelRef();
		if(!GetRef())
		{
			delete mptr;
		}
		mptr = NULL;
	}
	T& operator*()
	{
		return *mptr;
	}
	T* operator->()
	{
		return mptr;
	}
private:
	void AddRef()
	{
		rm->addRef(mptr);
	}
	void DelRef()
	{
		rm->delRef(mptr);
	}
	int GetRef()
	{
		return rm->getRef(mptr);
	}
private:
	T* mptr;
	static RefManage* rm;
};

template<class T>
RefManage* Shared_ptr<T>::rm = new RefManage::getInstance();

int main()
{
	int*p = new int;
	Shared_ptr<int> sp1(p);
	Shared_ptr<int> sp2(p);
	Shared_ptr<int> sp3(p);
	Shared_ptr<int> sp4(p);

	return 0;
}

Shared_ptr所存在的问题:

代码如下:

class B;
class A
{
public:
	A()
	{
		cout<<"A::A()"<<endl;
	}
	~A()
	{
		cout<<"A::~A()"<<endl;
	}
public:
	Shared_ptr<B> pa;
};
class B
{
public:
	B()
	{
		cout<<"B::B()"<<endl;
	}
	~B()
	{
		cout<<"B::~B()"<<endl;
	}
public:
	Shared_ptr<A> pb;
};

int main()
{
	Shared_ptr<A> spa(new A());
	Shared_ptr<B> spb(new B());
	spa->pa = spb;
	spb->pb = spa;
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值