谷歌的C++智能指针实现
//智能指针基类所有智能指针对象都继承该类
class RefCountedBase { public: virtual int AddRef()=0; virtual int Release()=0; protected: virtual ~RefCountedBase(){} };
智能指针对象类的实现
template <class T> class RefCountedPtr { public: RefCountedPtr() : m_ptr(NULL) { } RefCountedPtr(T* p) : m_ptr(p) { if (m_ptr)m_ptr->AddRef(); } RefCountedPtr(const RefCountedPtr<T>& r) : m_ptr(r.m_ptr) { if (m_ptr)m_ptr->AddRef(); } template <typename U> RefCountedPtr(const RefCountedPtr<U>& r) : m_ptr(r.get()) { if (m_ptr) m_ptr->AddRef(); } ~RefCountedPtr() { 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; } RefCountedPtr<T>& operator=(T* p) { // AddRef first so that self assignment should work if (p) p->AddRef(); if (m_ptr) m_ptr ->Release(); m_ptr = p; return *this; } RefCountedPtr<T>& operator=(const RefCountedPtr<T>& r) { return *this = r.m_ptr; } template <typename U> RefCountedPtr<T>& operator=(const RefCountedPtr<U>& r) { return *this = r.get(); } void swap(T** pp) { T* p = m_ptr; m_ptr = *pp; *pp = p; } void swap(RefCountedPtr<T>& r) { swap(&r.m_ptr); } protected: T* m_ptr; };
使用示例如下:
class MyClass:public RefCountedBase { public: ... virtual int AddRef() { return ++m_count; } virtual int Release() { int count = --m_count; if (!count) { delete this; } return count; } private: int m_count; }; RefCountedPtr<MyClass> test=new RefCountedObject<MyClass>()
使用C++模板可以省去每创建一个对象都要实现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 AtomicOps::Increment(&m_count); } virtual int Release() { int count = AtomicOps::Decrement(&m_count); if (!count) { delete this; } return count; } protected: virtual ~RefCountedObject() { } int m_count; };
使用方法如下:
class Test:public RefCountedBase { public: void test(){} }; //AddRef()及Release()方法由模板实现,无需再实现 RefCountedPtr<Test> test=new RefCountedObject<Test>() test->test();