智能指针(二)

上一篇博客将了两个智能指针auto_ptr和unique_ptr。指路智能指针(一)

今天我们继续来了解剩下的两个智能指针,shared_ptr和weak_ptr.

shared_ptr

特点:强智能指针,带有引用计数的指针,实现智能指针共享数据

           引用计数为0时,释放所指向的内存空间,所有权不唯一

缺点:智能指针相互引用,导致内存泄漏,

相互引用如图所示:

weak_ptr

特点:解决强智能指针shared_ptr相互引用的问题

            不能单独使用  配合shared_ptr

            不加引用计数   

#include<memory>

class Ref_Man
{
public:
	static Ref_Man* getInstance()
	{
		if (prm == NULL)
		{
			prm = new Ref_Man();
		}
		return prm;
	}
	int getRef(void* ptr)
	{
		if (ptr == NULL)
		{
			return -1;
		}
		int index = find(ptr);
		if (index != -1)
		{
			return ref_count[index].count;
		}
		return -1;
	}
	void addRef(void* ptr)
	{
		if (ptr == NULL)
		{
			return;
		}
		int index = find(ptr);
		if (index != -1)
		{
			ref_count[index].count++;
		}
		else
		{
			ref_count[cursize].addr = ptr;
			ref_count[cursize++].count = 1;
		}
	}
	void delRef(void* ptr)
	{
		if (ptr == NULL)
		{
			return;
		}
		int index = find(ptr);
		if (index != -1)
		{
			if (getRef(ptr) != 0)
			{
				--ref_count[index].count;
			}
		}
	}
private:
	Ref_Man()
	{
		cursize = 0;
	}
	Ref_Man(const Ref_Man&);
	int find(void* ptr)
	{
		int index = -1;
		for (int i = 0; i < cursize; i++)
		{
			if (ref_count[i].addr == ptr)
			{
				index = i;
				break;
			}
		}
		return index;
	}
	typedef struct Ref
	{
		void* addr;
		int count;
	}Ref;
	Ref ref_count[10];
	int cursize;
	static Ref_Man* prm;
};
Ref_Man* Ref_Man::prm = NULL;
template<typename T>
class Shared_Ptr
{
public:
	Shared_Ptr(T* ptr = NULL)
		:mptr(ptr)
	{
		prm->addRef(mptr);
	}
	Shared_Ptr(Shared_Ptr<T>& rhs)
	{
		mptr = rhs.mptr;
		prm->addRef(mptr);
	}
	Shared_Ptr<T>& operator=(Shared_Ptr<T>&rhs)
	{
		if (this != &rhs)
		{
			prm->delRef(mptr);
			if (prm->getRef(mptr))
			{
				delete mptr;
			}
			mptr = rhs.mptr;
			prm->addRef(mptr);
		}
		return *this;
	}
	~Shared_Ptr()
	{
		prm->delRef(mptr);
		if (prm->getRef(mptr) == 0)
		{
			delete mptr;
		}
		mptr = NULL;
	}
	T& operator*()
	{
		return *mptr;
	}
	T* operator->()
	{
		return mptr;
	}
private:
	T* mptr;
	static Ref_Man* prm;
};
template<typename T>
Ref_Man* Shared_Ptr<T>::prm = Ref_Man::getInstance();

class B;
class A
{
public:
	A()
	{
		std::cout << "A::A()" << std::endl;
	}
	~A()
	{
		std::cout << "A::~A()" << std::endl;
	}
public:
	std::weak_ptr<B> spa;
};
class B
{
public:
	B()
	{
		std::cout << "B::B()" << std::endl;
	}
	~B()
	{
		std::cout << "B::~B()" << std::endl;
	}
public:
	std::weak_ptr<A> spb;
};

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

int main()
{
	int* p = new int;
	Shared_Ptr<int> sp1(p);
	Shared_Ptr<double> spd = new double;
	Shared_Ptr<int> sp2(p);
	Shared_Ptr<int> sp3(p);
	return 0;
}

            

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值