#ifndef REFPTR_H #define REFPTR_H REFPTR_H /* Author: Josh Holtrop * Purpose: Provide a reference-counting pointer-like first order * C++ object that will free the object it is pointing to when * all references to it have been destroyed. * This implementation does not solve the circular reference problem. * I was not concerned with that when developing this class. */ #include /* NULL */ template class refptr { public: refptr(); refptr(T * ptr); refptr(const refptr & orig); refptr & operator=(const refptr & orig); refptr & operator=(T * ptr); ~refptr(); T & operator*() const { return *m_ptr; } T * operator->() const { return m_ptr; } bool isNull() const { return m_ptr == NULL; } private: void cloneFrom(const refptr & orig); void destroy(); T * m_ptr; int * m_refCount; }; template refptr::refptr() { m_ptr = NULL; m_refCount = NULL; } template refptr::refptr(T * ptr) { m_ptr = ptr; m_refCount = new int; *m_refCount = 1; } template refptr::refptr(const refptr & orig) { cloneFrom(orig); } template refptr & refptr::operator=(const refptr & orig) { destroy(); cloneFrom(orig); return *this; } template refptr & refptr::operator=(T * ptr) { destroy(); m_ptr = ptr; m_refCount = new int; *m_refCount = 1; return *this; } template void refptr::cloneFrom(const refptr & orig) { this->m_ptr = orig.m_ptr; this->m_refCount = orig.m_refCount; if (m_refCount != NULL) (*m_refCount)++; } template refptr::~refptr() { destroy(); } template void refptr::destroy() { if (m_refCount != NULL) { if (*m_refCount <= 1) { delete m_ptr; delete m_refCount; } else { (*m_refCount)--; } } } #endif