在软件系统中,指针的使用不当很容易导致两个主要的问题:
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();
}