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.
Singleton Object
-
- Greenskin
- Posts: 132
- Joined: Mon Aug 02, 2004 7:40 am
- Location: Austin, Texas
In the example Singleton code (near the bottom) of http://www.ogre3d.org/wiki/index.php/Singleton, I have a few questions:
This creates a pointer to a singleton of MyManager right? What would be the difference between this call? (I'm new to templates):
Why isn't an assert performed in the getSingletonPtr too? Or could it be?
Code: Select all
template<> MyManager* Singleton<MyManager>::ms_Singleton = 0;
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 );
}
-
- OGRE Retired Moderator
- Posts: 4823
- Joined: Fri Jun 18, 2004 1:40 pm
- Location: Berlin, Germany
- x 7
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)
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)
-
- OGRE Retired Team Member
- Posts: 3067
- Joined: Tue Feb 10, 2004 12:53 pm
- Location: The Netherlands
- x 1
-
- Greenskin
- Posts: 138
- Joined: Fri Feb 04, 2005 11:05 pm
- Location: Melbourne, Aus
Ah, I must have missed this thread the first time around - here's my solution: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.
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();
}
};
Cheers,
Mark
-
- Orc
- Posts: 468
- Joined: Sun Jul 10, 2005 11:44 am
- Location: Kiev, Ukraine
-
- Halfling
- Posts: 78
- Joined: Mon Jan 02, 2006 9:54 pm
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?
-
- OGRE Retired Team Member
- Posts: 3335
- Joined: Tue Jun 21, 2005 8:26 pm
- Location: Rochester, New York, US
- x 3
-
- Gnoblar
- Posts: 7
- Joined: Sat May 27, 2006 6:32 pm
-
- Gnoblar
- Posts: 9
- Joined: Tue Sep 04, 2007 5:27 am
Ogre::Singleton Doesn't Work With MSVC++ In Release Mode?
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
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
-
- OGRE Retired Team Member
- Posts: 3335
- Joined: Tue Jun 21, 2005 8:26 pm
- Location: Rochester, New York, US
- x 3