手动实现智能指针
转载注明出处:http://blog.csdn.net/you_lan_hai
//SmartPtr.h 智能指针 // author: 游蓝海 // blog: http://blog.csdn.net/you_lan_hai #ifndef LAZY3D_SMARTPTR_H #define LAZY3D_SMARTPTR_H #include <cassert> namespace Lazy { /** 引用计数类*/ class IBase { public: IBase(void) : m_nRefCounter_(0) { }; virtual ~IBase(void) { } /** 增加引用计数*/ void addRef(void) { ++m_nRefCounter_; } /** 减少引用计数*/ void delRef(void) { --m_nRefCounter_; if (m_nRefCounter_ <= 0) { destroyThis(); } } /** 获得引用计数*/ int getRef(void){ return m_nRefCounter_; } bool isRefUnique(){ return m_nRefCounter_ == 1; } virtual void destroyThis(void){ delete this; } private: int m_nRefCounter_ ;//引用计数 }; /** 智能指针基类*/ template<typename T> class BaseSmartPtr { public: BaseSmartPtr(T* ptr) : m_ptr(ptr) {} ~BaseSmartPtr(void){} T* operator->() const { assert(m_ptr && "智能指针未赋值!"); return m_ptr; } T& operator*() const { assert(m_ptr && "智能指针未赋值!"); return *m_ptr; } operator bool() const { return (m_ptr != NULL); } T* get() const { return m_ptr; } protected: T* m_ptr; }; /** 侵入式智能指针*/ template<typename T> class RefPtr : public BaseSmartPtr<T> { public: RefPtr() : BaseSmartPtr(0) { } RefPtr(T* ptr) : BaseSmartPtr(ptr) { safeAddRef(m_ptr); } RefPtr(const RefPtr<T>& ptr) : BaseSmartPtr(ptr.m_ptr) { safeAddRef(m_ptr); } ~RefPtr(void) { safeDelRef(m_ptr); } RefPtr<T>& operator=(T* ptr) { if (ptr != m_ptr) //防止自复制 { safeAddRef(ptr); safeDelRef(m_ptr); m_ptr = ptr; } return *this; } RefPtr<T>& operator=(const RefPtr<T>& ptr) { return *this = ptr.m_ptr;; } //强制类型转换 template<typename U> operator RefPtr<U>() { return RefPtr<U>((U*)m_ptr); } private: inline void safeAddRef(T * ptr) { if (ptr != NULL) { ptr->addRef(); } } inline void safeDelRef(T * ptr) { if (ptr != NULL) { ptr->delRef(); } } }; template<typename T, typename U> bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) { return (a.get() == b.get()); } template<typename T> bool operator==(const RefPtr<T>& a, const T* b) { return (a.get() == b); } template<typename T> bool operator==(const T* a, const RefPtr<T>& b) { return (a == b.get()); } template<typename T, typename U> bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) { return (a.get() != b.get()); } template<typename T> bool operator!=(const RefPtr<T>& a, const T* b) { return (a.get() != b); } template<typename T> bool operator!=(const T* a, const RefPtr<T>& b) { return (a != b.get()); } /** 非侵入式智能指针*/ template<typename T> class SmartPtr : public BaseSmartPtr<T> { public: typedef RefPtr<IBase> TypeRefCountPtr; typedef SmartPtr<T> TypeThis; SmartPtr() : BaseSmartPtr(0) { } //裸指针只能从构造函数传入 SmartPtr(T* ptr) : BaseSmartPtr(ptr) { if (m_ptr) { m_ref = new IBase(); //只有这一个地方生成引用计数对象 } } //拷贝构造函数 SmartPtr(const TypeThis& other) : BaseSmartPtr(other.m_ptr) , m_ref(other.m_ref) { } //强制类型转换过来的拷贝构造 template<typename U> SmartPtr(const SmartPtr<U> & other) : BaseSmartPtr(0) , m_ref(other.getRef()) { m_ptr = dynamic_cast<T*>(other.get()); } //析构函数 ~SmartPtr(void) { safeDelSelfPtr(); } TypeThis & operator=(const TypeThis & other) { if (this != &other) //防止自复制 { safeDelSelfPtr(); m_ptr = other.m_ptr; m_ref = other.m_ref; } return *this; } template<typename U> TypeThis & operator=(const SmartPtr<U> & other) { if ((void *)this != (void *)&other) //防止自复制 { safeDelSelfPtr(); m_ptr = dynamic_cast<T*>(other.get()); m_ref = other.getRef(); } return *this; } TypeRefCountPtr getRef() const { return m_ref; } int getRefCount() const { if (m_ref) { return m_ref->getRef(); } return 0; } private: inline void safeDelSelfPtr() { if (m_ref && m_ref->isRefUnique())//当引用计数唯一时,才释放被托管指针。 { delete m_ptr; } } TypeRefCountPtr m_ref; }; template<typename T, typename U> bool operator==(const SmartPtr<T>& a, const SmartPtr<U>& b) { return (a.get() == b.get()); } template<typename T, typename U> bool operator!=(const SmartPtr<T>& a, const SmartPtr<U>& b) { return (a.get() != b.get()); } }//namespace Lazy #endif //LAZY3D_SMARTPTR_H
1.侵入式智能指针托管的类,必须与IBase有同样的方法,可以让被托管类继承IBase,然后可被RefPtr托管。
2.非侵入式智能指针比较灵活,被托管类,完全不需要任何辅助接口。
RefPtr用法:
class A : public IBase{...};
main()
{
A* pA = new A();
RefPtr<A> ptr = pA;
ptr->methodOfA();
//不用释放pA指向的资源。
}
SmartPtr用法:
main()
{
SmartPtr<int> ptr(new int(0));
cout<<*ptr<<endl;
ptr = SmartPtr<int>(new int(10));
cout<<*ptr<<endl;
//不用释放new int分配的资源。
}