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

本文探讨了C++中由于指针使用不当导致的内存泄漏和过早删除问题,并提出通过引用计数来解决。引用计数机制使得对象能够自我管理生命周期,当引用计数为0时自动删除。文章介绍了如何不修改已有类实现,利用CRefCountObject作为容器,实现外置引用计数的智能指针功能。
摘要由CSDN通过智能技术生成

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

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();
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值