Skip to main content
gamedev.net
🔒 Locked

My singleton class

Started by JohanOfverstedt Sep 6, 2003 at 3:24 AM 9 replies 1.6k views
Original Post
JohanOfverstedt
JohanOfverstedt
Could you please quickly evaluate this singleton-class I have just written, so I can know if it''s a piece of crap or not It works by allocating the object the first time "getInstance()" is called, and is destroyed "atexit()" or when the user calls "releaseSingleton".

#ifndef COMMON_SINGLETON_H
#define COMMON_SINGLETON_H

#include <cassert>

template<class T>
class Singleton
{

private:

	static T *ms_instance;
	static bool ms_legalCreation;

public:

	Singleton() { assert(ms_legalCreation); }

	static T &getInstance() { 
		
		if(!ms_instance) 
		{ 
		
			ms_legalCreation = true;
			
			ms_instance = new T();
			
			atexit(releaseSingleton);
			
			ms_legalCreation = false;
	
		} 
	
		return *ms_instance; 
	
	}

	static T *getInstancePtr() {

		return &getInstance();

	}

	static void releaseSingleton() { if(ms_instance) { delete ms_instance; ms_instance = 0; } }

};

template <typename T> T* Singleton<T>::ms_instance = 0;
template <typename T> bool Singleton<T>::ms_legalCreation = false;

#endif

All comments are appreciated! My game: Swift blocks
DISCLAIMER: If any of the above statements are incorrect, feel free to deliver me a good hard slap!My games: DracMan | Swift blocks
antareus
antareus
Make the constructor private and then its impossible to instantiate unless you use getInstance.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
JohanOfverstedt
JohanOfverstedt
I tried doing that, but I then get compile errors, that my derived class''s constructor can''t access the Singleton class''s constructor etc.

I am using Visual C++ 6.0 by the way!

Thanks!

My game: Swift blocks
DISCLAIMER: If any of the above statements are incorrect, feel free to deliver me a good hard slap!My games: DracMan | Swift blocks
JohanOfverstedt
JohanOfverstedt
If I make the constructor protected in the base class and public in the derived class, then I can create instances of that class with for example: Test test;

Not what I want really

And as I said, when it is private, it won''t even compile!

My game: Swift blocks
DISCLAIMER: If any of the above statements are incorrect, feel free to deliver me a good hard slap!My games: DracMan | Swift blocks
antareus
antareus
Make it protected in the derived class?
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
JohanOfverstedt
JohanOfverstedt
I have tried it, then I can''t create the object from inside getInstance().

error C2248: ''Test::Test'' : cannot access protected member declared in class ''Test''

That''s the error message I get.
And then I have tried placing the Singleton constructor on all three places (private, protected and public).

My game: Swift blocks
DISCLAIMER: If any of the above statements are incorrect, feel free to deliver me a good hard slap!My games: DracMan | Swift blocks
Karl G
Karl G
Simple solution to the protected/private stuff... make the getInstance a friend function!
xiuhcoatl
xiuhcoatl
This is the way I have been doing it. This is basically an adaptation from Meyers/Scott Bilas/Greg Snook. It works quite well and is cleaner then using friends, statics, etc...


///////////////////////////////////////////////////////////////////////////////

//

// singleton.h

//

// Singleton template

//

// Encapsulates the mechanisms for doing a singleton into a template. To use

// the template singleton you only need to derive your class from the singleton

// (singleton acts as a base class) and use THE SAME class name as the

// typename. For example:

//

// class foo : public Singleton<foo>

// {

// someMethod( ARGS );

// };

//

// Then the only other requirement is to ensure that you allocate the object

// somewhere in the code ( preferably as early as possible ). Then you can

// access the object in the following manner:

//

// #define g_foo foo::getInstance()

// foo foo_Object;

//

// g_foo.someMethod( ARGS );

//

// It is recommended that the define go with the declaration/definition of the

// singleton class so that it is easily propogated to all users of the class.

//

// Original idea in Game Programming Gems 1 by Scott Bilas

// Other ideas by Greg Snook

///////////////////////////////////////////////////////////////////////////////

#ifndef singleton_h__
#define singleton_h__


// Disable the warning regarding ''this'' pointers being used in base member initializer list.

#pragma warning(disable : 4355)


template<class T> class Singleton
{
public:
Singleton(T& obj)
{
_ASSERT( !m_Singleton );
m_Singleton = &obj
}

~Singleton()
{
_ASSERT(m_Singleton);
m_Singleton = 0;
}

static T& __fastcall getInstance(void)
{
_ASSERT(m_Singleton);
return (*m_Singleton);
}

static T* __fastcall getInstancePtr(void)
{
return (m_Singleton);
}

private:
Singleton( const Singleton& Src);
Singleton& operator=( const Singleton& Src);


static T* m_Singleton;

};

template<class T> T* Singleton<T>::m_Singleton = 0;



#endif


The comments at the top of the file explain the use. I used to use a more complicated mechanism that hid the constructor, copy, assignment, and destructors away in a private declaration and would use reference counting. This way I could "create" the object as many times as I wanted but only the first creation actually did anything. This technique is a little more simplistic and instead bitches immediately if you try to create the same object in different places. I prefer that technique because the code is easier to maintain.

Each to his own I suppose...

Hope that helps..

#dth-0
"C and C++ programmers seem to think that the shortest distance between two points is the great circle route on a spherical distortion of Euclidean space."Stephen Dewhurst

Topic Locked

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

Sign in to reply to this topic.