|
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.
|