216 lines
4.1 KiB
C++
216 lines
4.1 KiB
C++
#ifndef _REF_CLASS_HPP_
|
||
#define _REF_CLASS_HPP_
|
||
|
||
/************************************************************************
|
||
|
||
自动管理生命期的引用计数对象实现类
|
||
|
||
以模板的函数提供对引用计数功能的实现,使用时直接将对象作为模板参数实
|
||
例化CRefObject或CMTRefObject即可。实例在构造时引用计数为0。当引用计数变
|
||
为0时会自动销毁实例。实现原理同于COM接口对象的引用计数;
|
||
|
||
对计数对象的使用必须严格遵循获取指针后立刻addRef,不用时release。
|
||
|
||
引用计数实现方式是多线程安全的。基于处理器原子保护锁的方式实现,增加以
|
||
及解 除引用的时候会锁住总线以便在多个处理器之间保持缓存一致性。是依靠硬
|
||
件实现的。
|
||
|
||
通常情况下使用CRefObject类完成自动化管理的对象引用功能,但如果直接使用
|
||
CRefObjectImpl模板类应当注意如下细节:
|
||
★在使用一个对象实例前必须调用addRef()函数以便增加引用计数;
|
||
★在解除对一个对象实例使用后必须调用release函数以便减少引用计数;
|
||
★不得使用delete销毁一个引用实例类,正确的做法是调用release解除引用;
|
||
★被实例化的类型只能使用new或malloc申请的内存块进行构造,不能对局部变
|
||
量或非指针类成员的对象使用引用计数实现。
|
||
|
||
***********************************************************************/
|
||
#ifndef _MSC_VER
|
||
#include "x_lock.h"
|
||
using namespace lock;
|
||
#endif
|
||
|
||
namespace misc
|
||
{
|
||
#ifdef _MSC_VER
|
||
typedef long COUNTTYPE;
|
||
#else
|
||
typedef int COUNTTYPE;
|
||
#endif
|
||
template <typename T>
|
||
class RefObjectImpl : public T
|
||
{
|
||
public:
|
||
RefObjectImpl(): T()
|
||
{
|
||
m_nRefer = 0;
|
||
}
|
||
//增加引用计数,函数返回增加引用后的引用计数值
|
||
inline void addRef()
|
||
{
|
||
#ifdef _MSC_VER
|
||
InterlockedIncrement(&m_nRefer);
|
||
#else
|
||
lock_.Lock();
|
||
m_nRefer++;
|
||
lock_.Unlock();
|
||
#endif
|
||
}
|
||
//减少引用计数,函数返回减少引用后的引用计数值
|
||
//当减少引用后引用计数为0则自动销毁对象自身。
|
||
inline void release()
|
||
{
|
||
#ifdef _MSC_VER
|
||
long n = InterlockedDecrement(&m_nRefer);
|
||
#else
|
||
lock_.Lock();
|
||
m_nRefer--;
|
||
int n = m_nRefer;
|
||
lock_.Unlock();
|
||
#endif
|
||
|
||
if (n <= 0)
|
||
finallRelease();
|
||
}
|
||
protected:
|
||
virtual void finallRelease()
|
||
{
|
||
delete this;
|
||
}
|
||
private:
|
||
COUNTTYPE m_nRefer; //引用计数
|
||
#ifndef _MSC_VER
|
||
Mutex lock_;
|
||
#endif
|
||
};
|
||
|
||
template <typename T>
|
||
class RefObject
|
||
{
|
||
protected:
|
||
RefObjectImpl<T>* m_ptr;//计数实现对象
|
||
public:
|
||
RefObject()
|
||
{
|
||
m_ptr = NULL;
|
||
}
|
||
RefObject(RefObject<T>& obj)
|
||
{
|
||
m_ptr = obj.m_ptr;
|
||
|
||
if (m_ptr)
|
||
m_ptr->addRef();
|
||
}
|
||
RefObject(RefObjectImpl<T>* pObj)
|
||
{
|
||
m_ptr = pObj;
|
||
|
||
if (m_ptr)
|
||
m_ptr->addRef();
|
||
}
|
||
virtual ~RefObject()
|
||
{
|
||
if (m_ptr) m_ptr->release();
|
||
}
|
||
|
||
//提供到模板实例化类型的转换函数
|
||
inline operator T* ()
|
||
{
|
||
return m_ptr;
|
||
}
|
||
inline operator const T* () const
|
||
{
|
||
return m_ptr;
|
||
}
|
||
//获取私有实现对象指针
|
||
inline RefObjectImpl<T>* raw_ptr()
|
||
{
|
||
return m_ptr;
|
||
}
|
||
inline const RefObjectImpl<T>* raw_ptr() const
|
||
{
|
||
return m_ptr;
|
||
}
|
||
|
||
//重载赋值运算函数,实现对象的引用
|
||
inline void operator = (RefObject<T>& obj)
|
||
{
|
||
if (&obj != NULL)
|
||
{
|
||
if (obj.m_ptr == m_ptr)
|
||
return;
|
||
|
||
//必须先为另一个对象的实例增加引用再减少当前实例的引用。
|
||
//藉此防止obj等于自己且引用计数为1在调用release后对象被删除而引发内存错误的问题。
|
||
if (obj.m_ptr) obj.m_ptr->addRef();
|
||
|
||
if (m_ptr) m_ptr->release();
|
||
|
||
m_ptr = obj.m_ptr;
|
||
}
|
||
else if (m_ptr)
|
||
{
|
||
m_ptr->release();
|
||
m_ptr = NULL;
|
||
}
|
||
}
|
||
//重载赋值运算函数,实现对象的引用
|
||
inline void operator = (RefObjectImpl<T>* pObj)
|
||
{
|
||
if (pObj != NULL)
|
||
{
|
||
if (pObj == m_ptr)
|
||
return;
|
||
|
||
if (pObj) pObj->addRef();
|
||
|
||
if (m_ptr) m_ptr->release();
|
||
|
||
m_ptr = pObj;
|
||
}
|
||
else if (m_ptr)
|
||
{
|
||
m_ptr->release();
|
||
m_ptr = NULL;
|
||
}
|
||
}
|
||
//重载相等性测试运算符
|
||
inline bool operator == (const RefObject<T>& obj) const
|
||
{
|
||
return obj.m_ptr == m_ptr;
|
||
}
|
||
inline void operator == (const RefObjectImpl<T>* pObj) const
|
||
{
|
||
return pObj == m_ptr;
|
||
}
|
||
inline void operator == (const int n) const
|
||
{
|
||
if (n == 0)
|
||
return m_ptr == NULL;
|
||
else return m_ptr != NULL;
|
||
}
|
||
//重载不等性测试运算符
|
||
inline bool operator != (const RefObject<T>& obj) const
|
||
{
|
||
return obj.m_ptr != m_ptr;
|
||
}
|
||
inline bool operator != (const RefObjectImpl<T>* pObj) const
|
||
{
|
||
return pObj != m_ptr;
|
||
}
|
||
inline void operator != (const int n) const
|
||
{
|
||
if (n == 0)
|
||
return m_ptr != NULL;
|
||
else return m_ptr == NULL;
|
||
}
|
||
inline bool operator !() const
|
||
{
|
||
return m_ptr == NULL;
|
||
}
|
||
};
|
||
};
|
||
|
||
|
||
#endif
|
||
|