This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  Smart Pointer Template Class
  Submitted by



This code snippet is from my upcoming book "Game Engine Design and Implementation using DirectX 8.1" and the contained "Realspace" game engine. It's a smart pointer template that has undergone a lot of testing. It mirrors the behaviour of normal pointers as closly as possible, however does not support the following things: *Pointers to base classes in class hierarchies
*Never create a smartpointer from an object allocated on the stack like Pointer p( &someClass ); because it could crash your programm since the memory would be freed as soon as the Pointer goes out of focus Everything else should work fine, and allows you to have multiple references to the same object which is automatically deleted when no objects refer it anymore. Also the class frees you of the troubles of NULL Pointer checking since that is done for you ( slows everything down, but you could blend it out in release builds ) You can use this code at your absolute free will.. Hope anyone finds it useful!
Bernhard Glück PS: I would like to hear suggestions, bug fixes or anything, and I am looking for some skilled graphics artists willing to help me out on my example game using the "Realspace" Engine (it's a space game")


Download Associated File: Pointer.h (6,492 bytes)

// -----------------------------------------------------------------------------
// 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 T> 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 <class T> inline Pointer<T>::Pointer( T * p ) { m_pointer = NULL; Set(p); }

// ----------------------------------------------------------------------------- template <class T> inline Pointer<T>::Pointer( const Pointer &p ) { m_pointer = p.m_pointer; m_pointer->count ++; }

// ----------------------------------------------------------------------------- template <class T> inline Pointer<T>::~Pointer() { Release(); }

// ----------------------------------------------------------------------------- template <class T> inline bool Pointer<T>::operator != ( const Pointer &p ) { if ( m_pointer != p.m_pointer ) return true; else return false; }

// ----------------------------------------------------------------------------- template <class T> inline bool Pointer<T>::operator == ( const Pointer &p ) { if ( m_pointer == p.m_pointer ) return true; else return false; }

// ----------------------------------------------------------------------------- template <class T> inline bool Pointer<T>::operator != ( const T * p ) { if ( m_pointer ) { if ( m_pointer->data == p ) return true; else return false; } else return true; }

// ----------------------------------------------------------------------------- template <class T> inline bool Pointer<T>::operator == ( const T * p ) { if ( m_pointer ) { if ( m_pointer->data != p ) return false; else return true; } else return false; }

// ----------------------------------------------------------------------------- template <class T> inline void Pointer<T>::operator = ( T * p ) { Set( p ); }

// ----------------------------------------------------------------------------- template <class T> inline void Pointer<T>::operator = ( const Pointer &p ) { Release();

m_pointer = p.m_pointer; m_pointer->count ++; }

// ----------------------------------------------------------------------------- template <class T> inline void Pointer<T>::Set( T * p ) { Release();

m_pointer = new PointerData(); m_pointer->data = p; m_pointer->count = 1; }

// ----------------------------------------------------------------------------- template <class T> inline void Pointer<T>::AddRef() { if ( m_pointer ) m_pointer->count ++; }

// ----------------------------------------------------------------------------- template <class T> inline void Pointer<T>::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 <class T> inline T* Pointer<T>::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 <class T> inline bool Pointer<T>::Valid() { if ( m_pointer ) { if ( m_pointer->data ) { return true; } else return false; } else return false; }

// ----------------------------------------------------------------------------- #endif // __POINTER_H__ // ----------------------------------------------------------------------------- // Pointer.h - End of file // -----------------------------------------------------------------------------

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.