Singleton Object

Get answers to all your basic programming questions. No Ogre questions, please!
User avatar
Clay
OGRE Community Helper
OGRE Community Helper
Posts: 518
Joined: Wed Mar 17, 2004 4:14 am
x 1

Post by Clay »

What the Ogre singleton does, is when you call the constructor, it saves a pointer to the created object in a static variable (just like you would a regular singleton).

The trick is, before this happens, it makes sure that the singleton pointer is NULL. If the singleton pointer is non-NULL then it raises an exception.

This does not do compile-time checking of singletons, it does runtime checking.
User avatar
bana
Greenskin
Posts: 132
Joined: Mon Aug 02, 2004 7:40 am
Location: Austin, Texas

Post by bana »

In the example Singleton code (near the bottom) of http://www.ogre3d.org/wiki/index.php/Singleton, I have a few questions:

Code: Select all

template<> MyManager* Singleton<MyManager>::ms_Singleton = 0;
This creates a pointer to a singleton of MyManager right? What would be the difference between this call? (I'm new to templates):

Code: Select all

MyManager* ms_Singleton = 0;

Code: Select all

MyManager* MyManager::getSingletonPtr(void)
{
    return ms_Singleton;
}
MyManager& ArchiveManager::getSingleton(void)
{  
    assert( ms_Singleton );  return ( *ms_Singleton );  
}
Why isn't an assert performed in the getSingletonPtr too? Or could it be?
A proud member of the OpenFrag Coding Team.
http://coolhands.blogspot.com/
User avatar
haffax
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4823
Joined: Fri Jun 18, 2004 1:40 pm
Location: Berlin, Germany
x 7

Post by haffax »

Not sure, but I think the intialisation is done this way, because of the C++ visiblity rules. ms_Singleton is declared in the Singleton template not in MyManager so you have to use the Singleton template for the scope.

The assert in getSingleton is important, because otherwise getSingleton() would fail and instead of an ugly access violation you get an assert with a bit more information. One could have designed the Singleton this way, that getSingleton() too asserts, but it is sometimes used to see if a Singleton has already been initialised (like it is done in the Ogre::Root constructor with the LogManager)
team-pantheon programmer
creators of Rastullahs Lockenpracht
User avatar
:wumpus:
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3067
Joined: Tue Feb 10, 2004 12:53 pm
Location: The Netherlands
x 1

Post by :wumpus: »

Dereferencing (the *) a 0 pointer would result in a very ugly error. That's why the assert is there.
getSingletonPtr() doesn't dereference the pointer, so it doesn't need the assert.
User avatar
CombatWombat
Greenskin
Posts: 138
Joined: Fri Feb 04, 2005 11:05 pm
Location: Melbourne, Aus

Post by CombatWombat »

sinbad wrote:However, the major clincher is that Meyer's doesn't allow for specialised singletons. For example, TextureManager is a singleton, but it's never an instance of TextureManager - it's created by plugins and will be D3D9TextureManager, GLTextureManager etc. Meyer's approach doesn't allow that.
Ah, I must have missed this thread the first time around - here's my solution:

Code: Select all

	template <class Ty> class SingletonHelper
	{
	public:
		// See Note (1) below regarding commented code in line below
		SingletonHelper() { /* mptObj = NULL; */ }
		~SingletonHelper()  {	delete mptObj; mptObj = NULL; }

		Ty *	getObj() { return mptObj; }

		void	setObj(Ty *ptPtr) { Assert(mptObj == NULL); mptObj = ptPtr; }

	private:
		// Note (1):
		// Horrible hack required by MSVC++ 6.0 compiler - when the compiler
		// inlines the Singleton/CreateFuncSingleton, it generates one
		// copy of the tSingletonHelper per translation unit that getSingleton()
		// is used in.  Yuk.
		static Ty *		mptObj;
	};

	template <class Tx> class CreateFuncSingleton
	{
	public:
		static Tx *		getSingleton()
		{
			// You need this to be a static object so it gets cleaned up 
			static SingletonHelper<Tx> tSingletonHelper;

			if (tSingletonHelper.getObj() == NULL)
				tSingletonHelper.setObj(Tx::create());

			return (Tx *) tSingletonHelper.getObj();
		}
	};
Just get your create to return the specialised type that's appropriate.

Cheers,

Mark
User avatar
yuriythebest
Orc
Posts: 468
Joined: Sun Jul 10, 2005 11:44 am
Location: Kiev, Ukraine

Post by yuriythebest »

so in other words getSingleton() could also have been named as createInstanceOfClass() or createClassInstance? Cause that's what it does- creates instances of classes, right?
User avatar
EtherealGF
Halfling
Posts: 78
Joined: Mon Jan 02, 2006 9:54 pm

Post by EtherealGF »

yuriythebest write
  • so in other words getSingleton() could also have been named as createInstanceOfClass() or createClassInstance? Cause that's what it does- creates instances of classes, right?
No, getSingleton() doesn't create instances, it returns the only one instance already created, what you have to do for creating an instance of the class is a new operator ....
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3

Post by Praetor »

Incidentally, something like createInstance is also a pattern of its own, like Singleton. That is called a factory method. It is in the same category as singleton in that it controls construction of objects (and sometimes lifetime), but they are not really the same thing.
msreddy
Gnoblar
Posts: 7
Joined: Sat May 27, 2006 6:32 pm

Update link on SIngleton

Post by msreddy »

cbudin
Gnoblar
Posts: 9
Joined: Tue Sep 04, 2007 5:27 am

Ogre::Singleton Doesn't Work With MSVC++ In Release Mode?

Post by cbudin »

Hi All,

I'm having problems getting the Ogre::Singleton implementation to work with Microsoft Visual C++ 2005 EE on Windows XP when compiling in Release mode. It seems that the Singleton class relies on assert() to detect a multiple instantiation situation and raise a runtime error, but assert() is turned off in Release mode (see assert.h). Has anyone else seen this, or know of a good way around it?

I think for my purposes I could just do a Meyers Singleton and be fine, but I'm curious if the community has dealt with this before.

Thanks,

Clay Budin
NYC
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3

Post by Praetor »

Generally not dealt with it, because such errors are usually caught in debug mode. You hunt down those violations, and then in release mode the asserts are off because it is assumed the errors were fixed.