http://www.liamdevine.co.uk

Singleton


Creative Commons License This work is licenced under a Creative Commons Licence.

[1]"Ensure a class only has one instance, and provide a global point of access to it."

This is the design pattern which is the most hotly contested on the net (see gamedev for examples) and used far too much by people who do not understand the consequences of using it, so I not going to enter into the debate yet instead just show the pattern.

Lets brake the pattern down
One instance: [2]"There can be only one", Yes but in Highlander there were many to start off with and in Highlander 965 is there only one?(back to the topic at hand).
Global point of access: This is like a global variable which people in OO circles seem to frown upon.


One instance
How can we ensure that there is only one instance(single thread)?
Well C++ inserts some functions called [3]special functions if a user does not define them, they are:
Default Constructor
Copy Constructor
and the Assignment Operator
A singleton does not want to be able to be copied, therefore creating another instance, so what we need to do is define these special functions in the none public interface to stop that. There is a general rule that I follow which is:
If you need to define one of these special functions then you probably will need to define all three.

class Foo
{

public:
	void bar();
private:
	Foo(){}
	Foo(Foo const& /*rhs*/){}

	Foo& operator = (Foo const & /*rhs*/){}
};
From looking at the example you can see that you can not create an instance of this class as the constructors are hidden and neither can it be copied. Please also notice that the parameters are commented out, this is stop a compiler warning message that the instance is declared yet not used.
So if the class can not be created how can there be an instance?
There are a couple of ways of doing this for instance the [4]Lazy Singleton pattern, yet this is not the method we are using here, instead creation is the responsibility of the Singleton template.
template<typename T>

class Singleton
{
public:
	static T* ptr()
	{

		if(!m_instance)m_instance = new T;
		return m_instance;
	}

private:	
	static T* m_instance;
	virtual ~Singleton(){ }
};

//initialise the static
template<typename T>T* Singleton<T>::m_instance = 0;
So you can see that the Singleton is the access point for the class, it allows the creation and access to it. Yet as it stands the Singleton template can not create the class, so lets carry on using the already shown examples. First we need the class (Foo) to inherit from the singleton to give it access to the get(ptr) function. Secondly to enable the singleton to create the instance it needs to be hooked into the class, this is acheived using the keyword friend, so we make the singleton a friend of this class.
class Foo : public Singleton<Foo>

{
public:
	void bar();
private:
	Foo(){}

	Foo(Foo const& /*rhs*/){}
	Foo& operator = (Foo const & /*rhs*/){}

	friend class Singleton<Foo>;
};
Are we nearly there yet(I need the toilet)?
Well we have a single instance and it has a point of access, but how do we delete it?
There is a function in cstdlib named atexit, to which you can register a function to be called when the application is exiting. With that lets rewrite the Singleton
#include <cstdlib>

template<typename T>

class Singleton
{
public:
	static T* ptr()
	{

		if(!m_instance)
		{
			m_instance = new T;
			atexit( &Singleton::destroy );
		}

		return m_instance;
	}
private:	
	static T* m_instance;

	virtual ~Singleton(){ }
	static destroy()
	{
		if(m_instance)
		{

			delete m_instance;
			m_instance = 0;//just for good measure its not really needed(read: old habit).
		}
	}
};

//initialise the static
template<typename T>T* Singleton<T>::m_instance = 0;
Ok so now we have a fully working singleton pattern that:
Ensures a class only has one instance, and provides a global point of access to it; in addition does not leak memory.

Is there anything more we can do?
Well the pattern is not thread safe and never will be in a platfrom agnostic way; as the current standard has no threading library. See Herb Sutter's blog here for more details on the next standard named C++0x.
I have heard of the double lock checking pattern for singletons.
Have you also read the paper [5]C++ and the Perils of Double-Checked Locking? If not go and read it if you need a threaded singleton, or just for an interesting read.

Edit: Ooo atomic types in 0x they have been getting talked about for a while and here Herb gives an example of the double checked locking pattern.

So you are still here and want to know about making it thread safe. Well I will shown you a Windows platform version and you should know why this is needed.
#ifndef SINGLETON_H_
#define		SINGLETON_H_

//not using windows threads directly, instead using my own platform wrapper it simplifies things :)
#include	"../include/mutex.h"

#include	<cstdlib>

#include	<windows.h>

extern "C" void _ReadWriteBarrier();
#pragma intrinsic(_ReadWriteBarrier)


///////////////////////////////////////////////////////////////////////////////
///  Class : Singleton
///  @Remarks :
///  This is a singleton template. It uses a mutex and a pointer to an instance
///  which is declared as volatile, so that the compiler does not cache its value.
///  When the singleton is called the first time, it uses the double check lock
///  pattern in conjuction with a memory barrier to stop the compiler messing with 
///  it, as the compiler can change the order of commands. The mutex could be 
///  locked on every call, but if the singleton is called n times then its not 
///  needed n-1 times.
///  ---------------------------------------------------------------------------
///  Heres an interesting paper from Scott Meyers about the problem of creating a
///  thread safe singleton.
///  http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
///  And heres how to use a memory barrier in the windows environment
///  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf_ReadWriteBarrier.asp
///
///  @License
///  This work is licenced under a Creative Commons Licence.
///  see:
///  http://creativecommons.org/licenses/by-nc-sa/3.0/
///  and:
///  http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
///  For more details.
///  
///  @author Liam Devine
///  @email: see www.liamdevine.co.uk for contact details.
///////////////////////////////////////////////////////////////////////////////


template< typename T >
class Singleton
{
public:

	///getter for the singleton template
	inline static T* ptr()
	{
		_ReadWriteBarrier();
		if( ! m_instance )//first check

		{
			m_mutex.lock();//lock the mutex

			if( ! m_instance )//second check

			{	//create the instance of the derived class
				m_instance = new T();
				_ReadWriteBarrier();

				//register the function to be called at exit
				atexit( &Singleton::destroy );	
			}
			m_mutex.unlock();//release the mutex

		}
		return (m_instance);//return the reference
	}
protected:
	///called when the app exits

	static void destroy()
	{ 
		if(m_instance)
		{ delete m_instance; m_instance = 0; } 
	}

	Singleton();///constructor
	~Singleton();///destructor
private:
	static T* volatile m_instance;//the instance of the singleton class

	static Mutex m_mutex;//mutex to make it threadsafe

	//declare two other functions so the compiler doesn't auto create
	//them, these are in private so that there is no way of calling them
	Singleton(const Singleton&);///none callable constructor
	Singleton& operator=(const Singleton&);///none callable operator

};


//initialise the statics
template<class T>T* volatile Singleton<T>::m_instance = 0;

template<class T>Mutex Singleton<T>::m_mutex;



#endif //SINGLETON_H_
So the final version (none thread safe) is here and it has another property which is an idea from [6]Alexandrescu's book. It is to control the life of the singleton, as you may not want the singleton to be around until the application exits.

Any comments or suggestions please see the contact method at the top of this page or post in my blog. Have fun, but always think is there another way to design without a singleton, as they make code none modular?
Parting thought: Singletons are horrible to refractor.


[1] Erich Gamma et al, "Design Patterns: elements of reusable object-oriented software", Addison Wesley (1995)
[2] Highlander (1986), http://www.imdb.com/title/tt0091203/, (visted 2/11/07)
[3] The C++ Standards Committee,"Working Draft, Standard for Programming Language C++", (2005)
[4] Microsoft Corp., Exploring the Singleton Design Pattern (http://msdn2.microsoft.com/en-us/library/ms954629.aspx), (visted 2/11/07)
[5] Scott Meyers and Andrei Alexandrescu, "C++ and the Perils of Double-Checked Locking", (2004)
[6] Andrei Alexandrescu , "Modern C++ Design: Generic Programming and Design Patterns Applied", Addison-Wesley (2001)

Files: singleton.h


About Me | Site Map | Valid xhtml? | ©2006 - 2013 Liam Devine