C++新特性25,26_强弱指针计数器增减分析及模拟强弱指针(主要还是原理介绍,初级只需要掌握使用即可;囫囵吞枣,具体的需要实际需要时结合视频理解)

接上篇:share_ptr与weak_ptr的源码分析本篇主要介绍强弱指针计数器增减分析并模拟强弱指针。

1. 关于强弱指针计数器增减分析

	//强指针构造,析构,=赋值,拷贝构造等情况下 计数器的变化
	//弱指针构造,析构,=赋值,拷贝构造等情况下 计数器的变化
	//弱指针提升为强指针时 计数器的变化

	//强指针直接构造(拿原始指针构造)时:
	//1.初始化_Ty *_Ptr
	//2.创建_Ref_count对象
	//3._Ref_count_base对象构造时,会分别为_Uses=1并且_Weaks=1

1.1 初始化及增加的情形:

  • 当创建一个新的shared_ptr时,内部对象计数器和自身的计数器均置1.
  • 当将另外一个shared_ptr赋值给新的shared_ptr时,内部对象计数器+1,自身计数器不变。
  • 当将另外一个shared_ptr赋值给新的weak_ptr时,内部对象计数器不变,自身计数器+1。
  • 当从weak_ptr获取一个shared_ptr时,内部对象计数器+1,自身计数器不变。

1.2 减少的情形:

  • 当一个shared_ptr析构时,内部对象计数器-1。当内部对象计数器减为0时,则释放内部对象,并将自身计数器-1。
  • 当一个weak_ptr析构时,自身计数器-1。当自身计数器减为0时,则释放自身_Ref_count*对象。

1.3学习视频地址:强弱指针计数器增减分析

2. 模拟强弱指针

经过前面的分析,我们彻底理解了智能指针的使用,因此,这里我们根据stl中的智能指针的写法,对自己版本的智能指针进行修改,从而到底彻底理解智能指针的目的。

2.1模拟代码:

#include <memory>
#include <tchar.h>

class CRefCount
{
public:
	CRefCount() {
		m_nUsedCount = 1;
		m_nWeakCount = 1;
	}

	void incUsed() {
		m_nUsedCount++;
	}

	int decUsed() {
		m_nUsedCount--;
		return m_nUsedCount;
	}

	void incWeak() {
		m_nWeakCount++;
	}

	int decWeak() {
		m_nWeakCount--;

		return m_nWeakCount;
	}

	int getUsed() {
		return m_nUsedCount;
	}

private:
	int m_nUsedCount; //强指针引用次数
	int m_nWeakCount; //弱指针引用次数
};

template<typename T>
class CMySmartPtrBase
{
public:
	CMySmartPtrBase() {};
	~CMySmartPtrBase() {};

	void destroy() {
		delete m_Ptr;
	}

	void release() {
		if (m_pRef != nullptr && m_pRef->decWeak() == 0) {
			delete m_pRef;
		}
	}

protected:
	T* m_Ptr;
	CRefCount* m_pRef;
};

//强指针类型
template<typename T>
class CMyWeakPtr;

template<typename T>
class CStrongPtr : public CMySmartPtrBase<T>
{
	friend class CMyWeakPtr<T>;
public:
	CStrongPtr() {
		m_Ptr = nullptr;
		m_pRef = nullptr;
	}

	explicit CStrongPtr(T* p) {
		m_Ptr = p;
		m_pRef = new CRefCount;
	}

	CStrongPtr(CStrongPtr<T>& obj) {

		m_Ptr = obj.m_Ptr;
		obj.m_pRef->incUsed();
		m_pRef = obj.m_pRef;
	}

	CStrongPtr<T>& operator=(CStrongPtr<T>& obj) {

		if (m_pRef != nullptr && m_pRef->decUsed() == 0) {
			destroy();
			release();
		}

		m_Ptr = obj.m_Ptr;
		obj.m_pRef->incUsed();
		m_pRef = obj.m_pRef;

		return *this;
	}

	CStrongPtr(CMyWeakPtr<T>& obj) {
		m_Ptr = obj.m_Ptr;
		obj.m_pRef->incUsed();
		m_pRef = obj.m_pRef;
	}

	~CStrongPtr() {
		if (m_pRef != nullptr && m_pRef->decUsed() == 0) {
			destroy();
			release();
		}
	}

	T& operator*() {
		return *m_Ptr;
	}

	T* operator->() {
		return m_Ptr;
	}

	T* get() {
		return m_Ptr;
	}
};


//强指针类型
template<typename T>
class CMyWeakPtr : public CMySmartPtrBase<T>
{
public:
	friend class CStrongPtr<T>;

	CMyWeakPtr() {
		m_Ptr = nullptr;
		m_pRef = nullptr;
	}

	CMyWeakPtr(CStrongPtr<T>& obj) {
		//release();

		m_Ptr = obj.m_Ptr;
		obj.m_pRef->incWeak();
		m_pRef = obj.m_pRef;
	}

	CMyWeakPtr<T>& operator = (CStrongPtr<T>& obj) {
		release();

		m_Ptr = obj.m_Ptr;
		obj.m_pRef->incWeak();
		m_pRef = obj.m_pRef;

		return *this;
	}

	CMyWeakPtr(CMyWeakPtr<T>& obj) {

		m_Ptr = obj.m_Ptr;
		obj.m_pRef->incWeak();
		m_pRef = obj.m_pRef;
	}

	~CMyWeakPtr() {
		release();
	}

	CStrongPtr<T>& lock() {
		if (m_pRef == nullptr) {
			return CStrongPtr<T>();
		}

		return CStrongPtr<T>(*this);
	}

	bool IsExpried() {
		if (m_pRef == nullptr) {
			return true;
		}

		return m_pRef->getUsed() == 0;
	}
};

class CSon;

class CTest {
public:

	void set(CStrongPtr<CSon> p2) {
		m_p1 = p2;
	}

	CStrongPtr<CSon> m_p1;
};

class CSon {
public:

	void set(CStrongPtr<CTest> p2) {
		m_p1 = p2;
	}

	CMyWeakPtr<CTest> m_p1;
};

void foo() {
	CTest* father = new CTest();
	CSon* son = new CSon();


	CStrongPtr<CTest> ptrFather(father);
	CStrongPtr<CSon> ptrSon(son);

	father->set(ptrSon);
	son->set(ptrFather);

}

int _tmain(int argc, _TCHAR* argv[])
{
	foo();

	return 0;
}

2.2 学习视频地址: 模拟强弱指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十月旧城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值