Original Post
Hey, I've been playing around with singletons this evening, I've come up with a design that will automatically construct and deconstruct itself making it amazingly simple to use. I've checked online and haven't seen anything like it so I thought I'd share it with you :-) Although if it has been done do correct me and send me on my merry way! All you have to do is in your class declaration is derive off CSingleton < CClassType >, and in your code CClassType::pInstance() to get the pointer to the instance of that class. It will create itself apon the first call to pInstance() and delete itself after calling ReleaseAutomaticSingletons(), telling it to delete all self created singletons. This can be prevented by constructing and deconstructing your singleton classes yourself, if your that way inclined! Source File: Header File: Declaration of class:
//----------------------------------------------------------------------------
//
// Bangz' Base Classes
// Richard Bangs - rbangs@gmail.com
//
//
// Title : CSingleton.cpp
// Desc :
// Author : Richard Bangs
//
// Notes :
//
//----------------------------------------------------------------------------
#include "CSingleton.h"
/////////////////////////////////////////////////////////////////////
// SingletonRelease System
// + Calling ReleaseAutomaticSingletons() will delete all the singletons
// that created themselves.
void* SingletonRelease_[ MAX_SELFRELEASINGSINGLETONS ];
int nSingletonRelease_ = 0;
/////////////////////////////////////////////////////////////////////
// ReleaseAutomaticSingletons
void ReleaseAutomaticSingletons()
{
for( int nSingleton = 0; nSingleton < nSingletonRelease_; nSingleton++ )
{
((CSingletonAutoRelease*)SingletonRelease_[ nSingleton ])->ReleaseMe();
SingletonRelease_[ nSingleton ] = NULL;
}
}
//----------------------------------------------------------------------------
//
// Bangz' Base Classes
// Richard Bangs - rbangs@gmail.com
//
//
// Title : CSingleton.h
// Desc :
// Author : Richard Bangs
//
// Notes :
//
//----------------------------------------------------------------------------
#ifndef __CSINGLETON_H__
#define __CSINGLETON_H__
#include "assert.h"
#ifndef NULL
#define NULL 0
#endif
const int MAX_SELFRELEASINGSINGLETONS = 50;
extern void* SingletonRelease_[ MAX_SELFRELEASINGSINGLETONS ];
extern int nSingletonRelease_ = 0;
void ReleaseAutomaticSingletons();
/////////////////////////////////////////////////////////////////////
// CSingletonAutoRelease
// - This class is an interface class so that a singleton template can
// call its own deletion without knowing its type from outside the class.
class CSingletonAutoRelease
{
public:
virtual void ReleaseMe() {};
};
/////////////////////////////////////////////////////////////////////
// CSingleton class
// - When Should I Use This Class?
// - This is a good base class for any class that is only ever going to
// have one instance. It provides the ability to get the pointer to its
// derived class without knowing where its been declared.
// - Example Syntax
// - Class declarations
// + class MyClass : public CSingleton < MyClass >
// - Usage
// + MyClass::pInstance()->MyFunction();
// - Additonal Notes
// - This works using the idea that there will be a different static
// variable for each template type, therefore if you attempt to try
// and create a class of the same type thats already in existance,
// pThis_ will already be set.
// - If this class hasn't been created apon first calling the pInstance()
// function it creates itself, it will also delete itself if this is the case.
template <class t>
class CSingleton : private CSingletonAutoRelease
{
public:
CSingleton();
virtual ~CSingleton();
static t* pInstance();
private:
virtual void ReleaseMe();
static t* pThis_;
};
template <class t>
t* CSingleton<t>::pThis_ = NULL;
/////////////////////////////////////////////////////////////////////
// Constructor
template <class t>
CSingleton<t>::CSingleton()
{
assert( !pThis_ ); // Singleton has already been created
pThis_ = (t*)(void*)this;
}
/////////////////////////////////////////////////////////////////////
// Destructor
//virtual
template <class t>
CSingleton<t>::~CSingleton()
{
pThis_ = NULL;
}
/////////////////////////////////////////////////////////////////////
// pInstance
// Returns an instance to the singleton class.
//static
template <class t>
t* CSingleton<t>::pInstance()
{
if( pThis_ == NULL )
{
// Class hasn't yet been created... Lets do that now.
pThis_ = new t;
// Set the class to automatically delete itself.
if( nSingletonRelease_ == MAX_SELFRELEASINGSINGLETONS )
{
assert( false ); // increase MAX_SELFRELEASINGSINGLETONS
}
SingletonRelease_[ nSingletonRelease_++ ] = (t*)pThis_;
}
return (t*)pThis_;
}
/////////////////////////////////////////////////////////////////////
// ReleaseMe
//virtual
template <class t>
void CSingleton<t>::ReleaseMe()
{
delete this;
}
#endif /* __CSINGLETON_H__ */
class CErrorLog : public CSingleton < CErrorLog >
{
public:
void CallMe();
}
Usage:
CErrorLog::pInstance()->CallMe();
Thought I'd share it with the world, seemed quite cool to me. Richard.