C++11增加了智能指针:shared_ptr、unique_ptr、weak_ptr
为了加深理解,自己实现智能指针
我们都知道shared_ptr的核心思想通过引用计数来管理内存
先实现单个指针的自我管理,看下面
template <class T>
class Ref
{
public:
Ref() : m_ptr(NULL)
{
}
Ref(T* p) : m_ptr(p)
{
if (m_ptr)m_ptr->AddRef();
}
Ref(const Ref<T>& r) : m_ptr(r.m_ptr)
{
if (m_ptr)m_ptr->AddRef();
}
template <typename U>
Ref(const Ref<U>& r) : m_ptr(r.get())
{
if (m_ptr) m_ptr->AddRef();
}
~Ref()
{
if (m_ptr) m_ptr->Release();
}
T* get() const { return m_ptr; }
operator T*() const { return m_ptr; }
T* operator->() const { return m_ptr; }
T* release()
{
T* retVal = m_ptr;
m_ptr = NULL;
return retVal;
}
Ref<T>& operator=(T* p)
{
if (p) p->AddRef();
if (m_ptr) m_ptr ->Release();
m_ptr = p;
return *this;
}
Ref<T>& operator=(const Ref<T>& r)
{
return *this = r.m_ptr;
}
template <typename U>
Ref<T>& operator=(const Ref<U>& r)
{
return *this = r.get();
}
void swap(T** pp)
{
T* p = m_ptr;
m_ptr = *pp;
*pp = p;
}
void swap(Ref<T>& r)
{
swap(&r.m_ptr);
}
protected:
T* m_ptr;
};
这部分不难理解
那么,再来需要管理的类的基类
//智能指针基类所有智能指针对象都继承该类
class RefCountedBase
{
public:
virtual int AddRef()=0;
virtual int Release()=0;
protected:
virtual ~RefCountedBase(){}
};
而我们自定义的类需要继承自此类,但是需要实现AddRef和Release,为了方便,再定义一个模板类用于管理计数
template <class T>
class RefCountedObject : public T
{
public:
RefCountedObject() : m_count(0)
{
}
template<typename P>
explicit RefCountedObject(P p) : T(p), m_count(0)
{
}
template<typename P1, typename P2>
RefCountedObject(P1 p1, P2 p2) : T(p1, p2), m_count(0)
{
}
template<typename P1, typename P2, typename P3>
RefCountedObject(P1 p1, P2 p2, P3 p3) : T(p1, p2, p3), m_count(0)
{
}
template<typename P1, typename P2, typename P3, typename P4>
RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4)
: T(p1, p2, p3, p4), m_count(0)
{
}
template<typename P1, typename P2, typename P3, typename P4, typename P5>
RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
: T(p1, p2, p3, p4, p5), m_count(0)
{
}
virtual int AddRef()
{
return m_count++;
}
virtual int Release()
{
int count = --m_count;
if (!count)
{
delete this;
}
return count;
}
protected:
virtual ~RefCountedObject() {
}
std::atomic_int m_count;
};
而我门在使用的时候,只需类似 shared_ptr的用法:
std::shared_ptr<Test> = std::make_shared<Test>();
class Test:public RefCountedBase
{
public:
void test(){}
};
Ref<Test> test=new RefCountedObject<Test>()
test->test();