Listing 1: Reference count template
#ifndef __RefCount_h__
#define __RefCount_h__
template<class DATA>
class CHReferenceCount
{
public:
CHReferenceCount();
CHReferenceCount(const CHReferenceCount<DATA>& objRefCount);
~CHReferenceCount();
CHReferenceCount<DATA>&
operator=(const CHReferenceCount<DATA> &robjRefCount);
void Reset();
protected:
inline const DATA* const GetData() const;
inline DATA* const GetData();
private:
// Reference counting implementation
void CopyOnWrite();
void CopyReference(const CHReferenceCount<DATA>& robjRefCount);
void NewReference();
void ReleaseReference();
inline int ReferenceCount();
DATA* m_pRefData; // pointer to shared data structure
int* m_pnRefCount; // pointer to reference counter
};
///////////////////////////////////////////////////////////////////
// inline functions
template<class DATA>
inline const DATA* const CHReferenceCount<DATA>::GetData() const
{
return m_pRefData;
}
template<class DATA>
inline DATA* const CHReferenceCount<DATA>::GetData()
{
if (ReferenceCount() > 1)
CopyOnWrite();
return m_pRefData;
}
template<class DATA>
inline int CHReferenceCount<DATA>::ReferenceCount()
{
return *m_pnRefCount;
}
///////////////////////////////////////////////////////////////////
// out-of-line functions
template<class DATA>
CHReferenceCount<DATA>::CHReferenceCount()
{
NewReference();
}
template<class DATA>
CHReferenceCount<DATA>::CHReferenceCount
(const CHReferenceCount<DATA>& robjRefCount)
{
CopyReference(robjRefCount);
}
template<class DATA>
CHReferenceCount<DATA>::~CHReferenceCount()
{
ReleaseReference();
}
template<class DATA>
CHReferenceCount<DATA>&
CHReferenceCount<DATA>::operator=
(const CHReferenceCount<DATA>& robjRefCount)
{
if (robjRefCount.m_pRefData != m_pRefData)
{
ReleaseReference();
CopyReference(robjRefCount);
}
return(*this);
}
template<class DATA>
void CHReferenceCount<DATA>::CopyReference
(const CHReferenceCount<DATA>& robjRefCount)
{
ASSERT(robjRefCount.m_pRefData && robjRefCount.m_pnRefCount);
m_pRefData = robjRefCount.m_pRefData;
m_pnRefCount = robjRefCount.m_pnRefCount;
++*m_pnRefCount;
}
template<class DATA>
void CHReferenceCount<DATA>::NewReference()
{
m_pRefData = new DATA;
m_pnRefCount = new int(1);
}
template<class DATA>
void CHReferenceCount<DATA>::ReleaseReference()
{
--*m_pnRefCount;
if (*m_pnRefCount == 0)
{
delete m_pnRefCount;
m_pnRefCount=NULL;
delete m_pRefData;
m_pRefData=NULL;
}
}
template<class DATA>
void CHReferenceCount<DATA>::CopyOnWrite()
{
DATA* pRefData = new DATA(*m_pRefData);
ReleaseReference();
m_pRefData = pRefData;
m_pnRefCount = new int(1);
}
template<class DATA>
void CHReferenceCount<DATA>::Reset()
{
ReleaseReference();
m_pRefData = new DATA;
m_pnRefCount = new int(1);
}
#endif
//End of File