Skip to main content
gamedev.net
🔒 Locked

Auto Constructing and Deconstructing Singleton

Started by bangz 2 replies 900+ views
Original Post
bangz
bangz
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:

//----------------------------------------------------------------------------
//
// 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;
	}
}


Header File:

//----------------------------------------------------------------------------
//
// 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__ */


Declaration of class:

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.
DrEvil
DrEvil
Should probably make ReleaseMe() null its pointer in the auto release array so there wont be a deleted pointer left to crash the app when you call ReleaseAutomaticSingletons() if you previously called ReleaseMe()
JohnBolton
JohnBolton
Rather than using an array, I recommend you use std::stack. That way destruction will be in the opposite order of construction and there is no limit to the number of singletons.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
penwan
penwan
I've been using the following. The class will automatically construct the first time Instance() is called and will automatically destruct when the program exits. It's much simpler. There are disadvantages, of course: there is no explicit control over creation/deletion, though that is the point of a singleton IMO.

The template:
template <typename T>class Singleton {public:    static T *Instance(void)    {        static T instance;        return &instance    }protected:    Singleton(void) {}    virtual ~Singleton(void) {}private:    Singleton(const Singleton &) {}};


A sample singleton:
#include "Singleton.h"class SomeClass : public Singleton<SomeClass>{    friend class Singleton<SomeClass>    // data goes herepublic:    void DoSomething(void)    {        // do something    }protected:    // Hide constructor/destructor -- this is a singleton    SomeClass(void);    SomeClass(const SomeClass &);    virtual ~SomeClass(void);};


Usage:
#include "SomeClass.h"SomeClass::Instance()->DoSomething();

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.