模仿的智能指针的一个简单实现

boost的智能指针特别强大,特别是 shared_ptr 和 weak_ptr

这几天看来下源代码,没多大理解,查了点资料,顺着自己理解的部分,实现了个简单的智能指针,

还木有实现线程安全,效率也没有boost的高。下面是代码



//SmartPtr.h
#pragma once
#include <map>
namespace cc
{
	class SmartPtrBase
	{
	protected:
		SmartPtrBase(){}
		static std::map<void*, int*>& RefCntMap();
	};

	template<typename T>
	class SharedPtr 
		: public SmartPtrBase
	{
	public:
		explicit SharedPtr(T* ptr = NULL) 
			: m_refCntMap(RefCntMap())
		{
				this->InitWithPtr(ptr);
		}

		SharedPtr(const SharedPtr& sharedPtr)
			: m_ptr(sharedPtr.m_ptr),
			m_refCntPtr(sharedPtr.m_refCntPtr),
			m_refCntMap(RefCntMap())
		{
			if (m_refCntPtr != NULL)
			{
				(*m_refCntPtr)++;
			}
		}

  //参考了boost的实现,下面使用了一个 friend class SharedPtr<Y>,
		template<class Y>
		SharedPtr(const SharedPtr<Y>& sharedPtr)	
			: m_ptr(sharedPtr.m_ptr),
			m_refCntPtr(NULL),
			m_refCntMap(RefCntMap())
		{
			if (m_refCntPtr != NULL)
			{
				(*m_refCntPtr)++;
			}
		}

		SharedPtr& operator=(const SharedPtr& sharedPtr)
		{
			if (this != &sharedPtr)
			{
				//防止自己赋值给自己时候误操作
				m_ptr = sharedPtr.m_ptr;
				m_refCntPtr = sharedPtr.m_refCntPtr;
				if (m_refCntPtr != NULL)
				{
					(*m_refCntPtr)++;
				}
			}
			return *this;
		}

		~SharedPtr()
		{
			Release();
		}

	public:
		//模拟正常指针行为

  //这个,我认为在同一个代码块里面,当智能指针对象还存在,
  //临时使用原始指针是安全的,但是不应该把这个值保存起来
  //如果需要保存可以再创建一个 SharedPtr对象
		operator T*() const
		{
			return m_ptr;
		}

		T& operator*() const
		{
			return *m_ptr;
		}

		T* operator->() const
		{
			return m_ptr;
		}

	private:
		void Release()
		{
			if (m_refCntPtr != NULL)
			{
				(*m_refCntPtr)--;
				if (*m_refCntPtr == 0)
				{
					delete m_refCntPtr;
					m_refCntMap[m_ptr] = NULL;
					delete m_ptr;
				}
			}
		}

		void InitWithPtr(T* ptr)
		{
			if (ptr != NULL)
			{
				m_ptr = ptr;
				m_refCntPtr = m_refCntMap[ptr];
				if (m_refCntPtr == NULL)
				{
					m_refCntPtr = new int(1);
					m_refCntMap[ptr] = m_refCntPtr;
				}
				else
				{
					(*m_refCntPtr)++;
				}
			}
			else
			{
				m_refCntPtr = NULL;
				m_ptr = NULL;
			}
		}

	private:
		T*		m_ptr;						//原始指针
		int*	m_refCntPtr;						//引用计数指针
		std::map<void*, int*>&		m_refCntMap;	//指针-引用计数 映射表

		template<class Y> friend class SharedPtr;
		template<class T> friend class WeakPtr;
	};

	template<typename T>
	class WeakPtr 
		: public SmartPtrBase
	{
	public:
		template<class Y>
		WeakPtr(const SharedPtr<Y>& ptr) 
			: m_ptr(ptr.m_ptr),
			m_refCntMap(RefCntMap())
		{
		}

		template<class Y>
		WeakPtr(const WeakPtr<Y>& ptr) 
			: m_ptr(ptr.m_ptr),
			m_refCntMap(RefCntMap())
		{
		}

		SharedPtr<T> Lock()
		{
			int* refCnt = m_refCntMap[m_ptr];
			if (refCnt == NULL)
			{
  //这时候指针事实上已经销毁了
  //这个稍微解释下,抛出个 cc::Exception 子异常,后面是异常附带消息
				THROW_CC_EXCEPTION_MSG(NullPointerException, "pointer expired");
			}

			return SharedPtr<T>(m_ptr);
		}

	private:
		T*		m_ptr;
		std::map<void*, int*>&		m_refCntMap;	//指针-引用计数 映射表
		template<class T> friend class WeakPtr;
	};
}


SmartPtr.cpp
#include "SmartPtr.h"

namespace cc
{
	std::map<void*, int*>& SmartPtrBase::RefCntMap()
	{
		static std::map<void*, int*> smartPtrRefCntMap;
		return smartPtrRefCntMap;
	}
}


有任何改进效率建议请务必给我留言或者发邮件,由衷感谢!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值