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;
};
}
#include "SmartPtr.h"
namespace cc
{
std::map<void*, int*>& SmartPtrBase::RefCntMap()
{
static std::map<void*, int*> smartPtrRefCntMap;
return smartPtrRefCntMap;
}
}
有任何改进效率建议请务必给我留言或者发邮件,由衷感谢!