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.