// ----------------------------------------------------------------------------- // File contents / class description: // ----------------------------------------------------------------------------- // // Smart pointer template class // // ----------------------------------------------------------------------------- // Originally created on 05/15/2000 by Bernhard Glueck // Email: jglueck@vol.at // You can use this software at your own free will, however I am not to be held // responsible for any damage this does to you or to your health :-) // You can freely use the code provided in your own programs, however if you find // any bugs, or add a cool new feature to it, I would like to hear about it. // ----------------------------------------------------------------------------- #ifndef __POINTER_H__ #define __POINTER_H__ /// Disable UDT warning #pragma warning ( disable : 4284 ) // ----------------------------------------------------------------------------- /// Error handling macro only for this version #define ErrorReport( a ) /// A simple macro for relasing C++ classes safely #define SafeRelease( object ) if ( object ) delete object /// SmartPointer template which offers automatic reference counting template class Pointer { public: struct PointerData { T * data; int count; }; /// Assigns a native pointer inline void operator = ( T * p ); /// Assigns another smartpointer inline void operator = ( const Pointer &p ); /// Compares two smartpointers inline bool operator == ( const Pointer &p ); /// The same only negative inline bool operator != ( const Pointer &p ); /// Compares a smartpointer and a native pointer inline bool operator == ( const T * p ); /// Compares a smartpointer and a native pointer, negative inline bool operator != ( const T * p ); /// Accesses the native pointer inline const T * operator -> () { return Get(); } /// Dereferences the native pointer inline T & operator * () { return *Get(); } /// Checks if the native pointer is valid inline bool Valid(); /// Converts the pointer to native inline operator const T * () { return Get(); } /// Releases the referenced object (safe) inline void Release(); /// Retrieves the native pointer... inline T * Get(); /// Increases the reference count by one, use with extreme CAUTION! inline void AddRef(); // Construction/Destruction inline Pointer( T * p = NULL ); inline Pointer( const Pointer & ); inline ~Pointer(); private: inline void Set( T * p ); // Data members PointerData * m_pointer; }; // ----------------------------------------------------------------------------- template inline Pointer::Pointer( T * p ) { m_pointer = NULL; Set(p); } // ----------------------------------------------------------------------------- template inline Pointer::Pointer( const Pointer &p ) { m_pointer = p.m_pointer; m_pointer->count ++; } // ----------------------------------------------------------------------------- template inline Pointer::~Pointer() { Release(); } // ----------------------------------------------------------------------------- template inline bool Pointer::operator != ( const Pointer &p ) { if ( m_pointer != p.m_pointer ) return true; else return false; } // ----------------------------------------------------------------------------- template inline bool Pointer::operator == ( const Pointer &p ) { if ( m_pointer == p.m_pointer ) return true; else return false; } // ----------------------------------------------------------------------------- template inline bool Pointer::operator != ( const T * p ) { if ( m_pointer ) { if ( m_pointer->data == p ) return true; else return false; } else return true; } // ----------------------------------------------------------------------------- template inline bool Pointer::operator == ( const T * p ) { if ( m_pointer ) { if ( m_pointer->data != p ) return false; else return true; } else return false; } // ----------------------------------------------------------------------------- template inline void Pointer::operator = ( T * p ) { Set( p ); } // ----------------------------------------------------------------------------- template inline void Pointer::operator = ( const Pointer &p ) { Release(); m_pointer = p.m_pointer; m_pointer->count ++; } // ----------------------------------------------------------------------------- template inline void Pointer::Set( T * p ) { Release(); m_pointer = new PointerData(); m_pointer->data = p; m_pointer->count = 1; } // ----------------------------------------------------------------------------- template inline void Pointer::AddRef() { if ( m_pointer ) m_pointer->count ++; } // ----------------------------------------------------------------------------- template inline void Pointer::Release() { if ( m_pointer ) { m_pointer->count --; if ( m_pointer->count == 0 ) { if ( m_pointer->data ) { delete m_pointer->data; m_pointer->data = NULL; } delete m_pointer; // This can only happen when no objects still refer it } // Very important m_pointer = NULL; } } // ----------------------------------------------------------------------------- template inline T* Pointer::Get() { if ( m_pointer ) { if ( m_pointer->data ) { return m_pointer->data; } else { ErrorReport("Trying to access NULL pointer"); return NULL; } } else { ErrorReport("Pointer access error"); // Only for syntax, should never happen! return NULL; } } // ----------------------------------------------------------------------------- template inline bool Pointer::Valid() { if ( m_pointer ) { if ( m_pointer->data ) { return true; } else return false; } else return false; } // ----------------------------------------------------------------------------- #endif // __POINTER_H__ // ----------------------------------------------------------------------------- // Pointer.h - End of file // -----------------------------------------------------------------------------