c++引用计数外置方式模板实现

来源:互联网 发布:内存条数据怎么看 编辑:程序博客网 时间:2024/04/28 20:09

在软件系统中,指针的使用不当很容易导致两个主要的问题:

1.内存泄漏,当指针一直得不到释放时就会发生这种情况。随着时间的过去。当应用程序的内存消耗无法控制时,内存泄漏就会使应用程序终止运行。

2.过早删除,当指针的所有关系不清楚时,会导致访问已释放的内存,这将造成灾难性的破坏。

然而在C++中,允许你控制对象的创建、清楚、复制。通过开发一种称为引用计数的垃圾回收机制,可以实现这种控制。

其基本思想就是把对象清楚的责任从客户端代码转移到对象本身,对象自己跟踪当前对它的引用数量,并在引用数量达到0时删除自己。

现在很多的编译器都支持C++智能指针std::tr1::shared_ptr模板。今天自己写一个引用计数和智能指针


功能:不需要修改已有的类实现,直接使用CRefCountObject作为“容器”,由其去管理引用计数。

template<class _Ty>class CRefCountObject{public:CRefCountObject(_Ty* _pointee) :m_pointee(_pointee), m_lRefCount(1){}CRefCountObject(const CRefCountObject& rhs){rhs.AddRef();m_lRefCount = rhs.m_lRefCount;m_pointee = rhs.m_pointee;}CRefCountObject& operator = (const CRefCountObject& rhs){rhs.AddRef();m_lRefCount = rhs.m_lRefCount;m_pointee = rhs.m_pointee;return this;}virtual ~CRefCountObject(){if (m_pointee != NULL){delete m_pointee;m_pointee = NULL;}}_Ty* _Get()const{return (m_pointee != NULL ? m_pointee : NULL);}long _UseCount()const{return (m_pointee !=NULL? m_lRefCount : 0);}void AddRef();void RemoveRef();private:long m_lRefCount;  bool m_bShareable; _Ty* m_pointee;};template<class _Ty>void CRefCountObject<_Ty>::AddRef(){InterlockedIncrement(&m_lRefCount);}template<class _Ty>void CRefCountObject<_Ty>::RemoveRef(){long lRefCount = InterlockedDecrement(&m_lRefCount);if (0 == lRefCount){delete this;}}


template<class _Ty>class CMySharedPtr {public:CMySharedPtr() :m_pRefCountObject(NULL){}CMySharedPtr(_Ty* realPtr = NULL) :m_pRefCountObject(new _RefCtTy(realPtr)){}CMySharedPtr(const CMySharedPtr& rhs) :m_pRefCountObject(rhs.m_pRefCountObject){m_pRefCountObject->AddRef();}CMySharedPtr& operator= (const CMySharedPtr& rhs){if (*this != rhs && this->m_pRefCountObject != rhs.m_pRefCountObject){m_pRefCountObject->RemoveRef();m_pRefCountObject = rhs.m_pRefCountObject;}return *this;}~CMySharedPtr(){if (m_pRefCountObject != NULL) m_pRefCountObject->RemoveRef();}_Ty* get()const;_Ty* operator ->()const;long use_count()const;private:_RefCtTy* m_pRefCountObject;};template<class _Ty>_Ty* CMySharedPtr<_Ty>::get()const{if (m_pRefCountObject != NULL){return m_pRefCountObject->_Get();}return NULL;}template<class _Ty>_Ty* CMySharedPtr<_Ty>::operator ->()const{if (m_pRefCountObject != NULL){return m_pRefCountObject->_Get();}return NULL;}template<class _Ty>long CMySharedPtr<_Ty>::use_count()const{return m_pRefCountObject->_UseCount();}



0 0