// http://www.josuttis.com/libbook/cont/countptr.hpp.html // http://en.wikipedia.org/wiki/Auto_ptr // http://www.koders.com/cpp/fidAD7781CE87A3E6FF6EEAE0B813566BDCC8EE7B1A.aspx?s=mdef%3Ainsert // file:///home/moma/code/thinking/html/TicV2.html#_Toc305593296 #pragma once #include struct NullPointerException : public std::runtime_error { explicit NullPointerException (const char *s = "Null pointer error") : std::runtime_error (s) { // std::cerr << "Assertion failed in file " << __FILE__ << " at line " << __LINE__ << ":" << std::endl; // std::cerr << #expression << std::endl; } void raise () { throw *this; } }; template class AutoPtr { private: T *m_ptr; // Pointer long *m_count; // Reference count public: // initialize pointer with existing pointer // - requires that the pointer p is a return value of new explicit AutoPtr (T* p=0) : m_ptr(p), m_count(new long(1)) { } // copy pointer (one more owner) AutoPtr (const AutoPtr& p) throw() : m_ptr(p.m_ptr), m_count(p.m_count) { ++*m_count; } // destructor (delete value if this was the last owner) ~AutoPtr () throw() { dispose(); } // assignment (unshare old and share new value) AutoPtr& operator= (const AutoPtr& p) throw() { if (this != &p) { dispose(); m_ptr = p.m_ptr; m_count = p.m_count; ++(*m_count); } return *this; } // access the value to which the pointer refers T& operator*() const throw() { if (m_ptr == 0) { throw NullPointerException("Null pointer exception in operator*() of class AutpPtr"); } return *m_ptr; } T* operator->() const throw() { if (m_ptr == 0) { throw NullPointerException("Null pointer exception in operator->() of class AutpPtr"); } return m_ptr; } const T *getPtr() const { return m_ptr; } const T &getRef() const { if (m_ptr == 0) { throw NullPointerException("Null pointer exception in getRef() of class AutpPtr"); } return *m_ptr; } // Explicitly delete the data pointer. void explicitly_delete() { if (m_ptr) delete m_ptr; m_ptr = 0; *m_count = 0; } // Get reference count (number pointers on this object) long getRefCount() { return *m_count; } // Compare operators bool operator == (const AutoPtr& p) const { return getPtr() == p.getPtr(); } bool operator == (const T* p) const { return getPtr() == p; } bool operator == (T* p) const { return getPtr() == p; } bool operator != (const AutoPtr& p) const { return getPtr() != p.getPtr(); } bool operator != (const T* p) const { return getPtr() != p; } bool operator != (T* p) const { return getPtr() != p; } bool operator < (const AutoPtr& p) const { return getPtr() < p.getPtr(); } bool operator < (const T* p) const { return getPtr() < p; } bool operator < (T* p) const { return getPtr() < p; } bool operator <= (const AutoPtr& p) const { return getPtr() <= p.getPtr(); } bool operator <= (const T* p) const { return getPtr() <= p; } bool operator <= (T* p) const { return getPtr() <= p; } bool operator > (const AutoPtr& p) const { return getPtr() > p.getPtr(); } bool operator > (const T* p) const { return getPtr() > p; } bool operator > (T* p) const { return getPtr() > p; } bool operator >= (const AutoPtr& p) const { return getPtr() >= p.getPtr(); } bool operator >= (const T* p) const { return getPtr() >= p; } bool operator >= (T* p) const { return getPtr() >= p; } private: void dispose() { if (*m_count > 0) (*m_count)--; if (*m_count == 0) { delete m_count; delete m_ptr; } } };