diff --git a/refptr.h b/refptr.h new file mode 100644 index 0000000..7335af5 --- /dev/null +++ b/refptr.h @@ -0,0 +1,99 @@ + +#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