#ifndef __REF_H__ #define __REF_H__ ////////////////////////////////////////////////////////////////////////////// // class Referenc // Desc: Base class enabling reference interface // Note: Class should derive as virtual // class Referenc { public: Referenc() : refs_count(0) {}; inline int AddRef() { return ++refs_count; } inline int RemRef() { return --refs_count; } inline int RefCount() { return refs_count; } private: int refs_count; }; ////////////////////////////////////////////////////////////////////////////// // template Ref // Desc: Holder in smart-pointers system. // Important: Only Referenc subclasses may be used as template param. // template class Ref { public: // Constructors & destructor Ref(); //Ref(Ref &ref); Ref(const Ref &ref); Ref(T *ptr); Ref(const T *ptr); ~Ref(); Ref &operator =(Ref &ref); Ref &operator =(T *ptr); inline T *Addr(); inline T *Addr() const; inline int RefCount(); inline bool IsNull(); inline T *operator ->(); inline operator const T *() const; inline operator T *(); //private: void RemRef(); private: T *m_ptr; }; ////////////////////////////////////////////////////////////////////////////// // Constructors & destructor template Ref::Ref() : m_ptr(NULL) { } //template Ref::Ref(Ref &ref) //: m_ptr(NULL) //{ // if (ref.Addr() != NULL) // { // m_ptr = ref.Addr(); // ((Referenc *)m_ptr)->AddRef(); // } //} template Ref::Ref(const Ref &ref) : m_ptr(NULL) { if (ref.Addr() != NULL) { m_ptr = ref.Addr(); ((Referenc *)m_ptr)->AddRef(); } } template Ref::Ref(T *ptr) : m_ptr(NULL) { if (ptr != NULL) { m_ptr = ptr; ((Referenc *)m_ptr)->AddRef(); } } template Ref::Ref(const T *ptr) : m_ptr(NULL) { if (ptr != NULL) { m_ptr = ptr; ((Referenc *)m_ptr)->AddRef(); } } template Ref::~Ref() { if (m_ptr == NULL) return; RemRef(); } // Check pointer on correctness template bool Ref::IsNull() { return (m_ptr == NULL); } ////////////////////////////////////////////////////////////////////////////// // Operators template Ref &Ref::operator =(T *ptr) { if (ptr != NULL) { if (m_ptr != ptr) { RemRef(); m_ptr = ptr; ((Referenc *)m_ptr)->AddRef(); } } else if (m_ptr != NULL) RemRef(); return *this; } template Ref &Ref::operator =(Ref &ref) { if (ref.Addr() != NULL) { if (m_ptr != ref.Addr()) { RemRef(); m_ptr = ref.Addr(); ((Referenc *)m_ptr)->AddRef(); } } else if (m_ptr != NULL) RemRef(); return *this; } // Get pointer template T *Ref::Addr() { return m_ptr; } template T *Ref::Addr() const { return m_ptr; } // Get refs count template int Ref::RefCount() { if (m_ptr == NULL) return 0; return ((Referenc *)m_ptr)->RefCount(); } // Remove ref to the object and delete it if necessary // WARNING: arrays cannot be deleted template void Ref::RemRef() { if (m_ptr == NULL) return; if (((Referenc *)m_ptr)->RemRef() == 0) delete m_ptr; m_ptr = NULL; } template T *Ref::operator ->() { return m_ptr; } template Ref::operator const T *() const { return m_ptr; } template Ref::operator T *() { return m_ptr; } #endif // __REF_H__