-Singleton        

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | 0-9


Singleton - A class of which only one instance can exist at a given time. This instance can be accessed from anywhere in the program without passing a reference to it around. A useful design pattern, but apply with care.

A general approach

Forum Answer

Taken from here here:

Mdobele:Singleton Classes rock. Simply think of it as a way of ensuring that the class you are calling is created only once. That means it can be called from anywhere ( by including header of course ) and you know that your calling the 1 static instance and not creating another instance.

I use them mostly for my main application and then for every single "manager" class that I use.

Here is an example of a Menu manager

// Class Declaration
class MenuManager
{
public :
   
   // Constructor
   MenuManager();

   // Destructor
   ~MenuManager();

   // SingleTon Instance
   // Singleton Instance of our Menu manager
   static MenuManager &Instance();

   // Create Main Menu
   void CreateMainMenu();

private:
   InheritedBase *m_BaseMenu;
   MainMenu * m_MainMenu;
};
And the .cpp
//SingleTon Instance
MenuManager &MenuManager::Instance()
{
   static MenuManager instance;
   return instance;
}

// Create MainMenu
void MenuManager::CreateMainMenu()
{
   m_MainMenu = new MainMenu();
   m_MainMenu->CreateMainMenu();
}

So in any other file i simply include

#include MenuManager.h

and I gain acess to it Knowing that its the one and only and not another instance.

MenuManager::Instance().CreateMainMenu();

Hope that clears it up a bit.


bal:
IIRC, singletons are a design pattern (a way of creating classes that fits in most projects). There are a lot of different implementations but the point is always the same: having ONLY ONE instance of a class.

Ogre's approach

Description

Ogre's implementation differs in a couple of points from the approach described above.

  • Ogre::Singleton is a template, meaning you must instantiate it with the type, that you want to have as a Singleton. This allows us to handle all Singletons with the same code, which makes the code a bit more maintainable.
  • Ogre::Singleton must be constructed explicitly. You must call the constructor of your Singleton class, before you can obtain a reference to the instance. The implementation described above creates the singleton on the fly when the instance is obtained for the first time. The advantage of Ogre's implementation is that you can instantiate it with arbitrary parameters.


The Source can be found here.

How to use it


NOTE: In Ogre 1.7, the static member msSingleton we are referring to below will actually be called ms_Singleton. The code below assumes you use Ogre 1.8 or later.

Making a class a singleton

Pretend we want to convert the class MyManager to a Singleton.

class MyManager
{
public:
    MyManager();
    void doSomething();
};

So we need to extend and instantiate the Ogre::Singleton template and override the singleton access methods. Our header file will look like this:

#include <OgreSingleton.h>
class MyManager : public Ogre::Singleton<MyManager>
{
public:
    MyManager();
    void doSomething();
    static MyManager& getSingleton(void);
    static MyManager* getSingletonPtr(void);
};

You don't have to override getSingleton() and getSingletonPtr() if your Singleton is not used outside of your EXE/DLL, but else you have to.
The source file would now look like this:

#include "MyManager.h"

template<> MyManager* Ogre::Singleton<MyManager>::msSingleton = 0;
MyManager* MyManager::getSingletonPtr(void)
{
    return msSingleton;
}
MyManager& MyManager::getSingleton(void)
{  
    assert( msSingleton );  return ( *msSingleton );  
}

// The rest of your implementation is following.
...

Making a class (in another namespace) a singleton

If you want to make a class from a specific namespace a singleton, you cannot use the previous method.
Due to C++ specification (C++ Standard 14.7.3/2) you cannot specialize a template (like Ogre::Singleton<T>) in other namespace than its declaration's one.
Here is a complement to the previous technique.

There is two case where you need another namespace :

  1. Your class is a part of an application directly using Ogre3D
  2. Your class is a part of a library (DLL) directly using Ogre3D but, like all DLLs, attends to be used by another program.


The two cases are pretty close.
The fellowing code is needed only for the case 2. A good practice when developping a DLL is to define a macro for export/import depending on the building situation (building the lib itself => export ; build an app with the lib => import).

// File MyLibPrereq.h
#	if defined(MYLIB_NONCLIENT_BUILD)
// Export definition
#		define _MYLIBExport __declspec( dllexport )
#	else
// Import definition
#		define _MYLIBExport __declspec( dllimport )
#	endif


The header file for MyManager in case 1 :

#include "MyLibPrereq.h"
#include <OgreSingleton.h>
namespace MyLib { class MyManager; }

template class _OgreExport Ogre::Singleton<MyLib::MyManager>; // export of explicit instantiation

namespace MyLib
{
class MyManager : public Ogre::Singleton<MyManager>
{
public:
    MyManager();
    void doSomething();
    static MyManager& getSingleton(void);
    static MyManager* getSingletonPtr(void);
};
}


Now the header for MyManager in case 2. The difference reside in the export directive, here we use our own directive :

#include "MyLibPrereq.h"
#include <OgreSingleton.h>
namespace MyLib { class MyManager; }

template class _MYLIBExport Ogre::Singleton<MyLib::MyManager>; // export of explicit instantiation

namespace MyLib
{
class MyManager : public Ogre::Singleton<MyManager>
{
public:
    MyManager();
    void doSomething();
    static MyManager& getSingleton(void);
    static MyManager* getSingletonPtr(void);
};
}


Then the source for case 2:

#include "MyManager.h"

// Template specialization
template<> _MYLIBExport MyLib::MyManager* Ogre::Singleton<MyLib::MyManager>::msSingleton = 0;

namespace MyLib
{
MyManager* MyManager::getSingletonPtr(void)
{
    return msSingleton;
}
MyManager& MyManager::getSingleton(void)
{  
    assert( msSingleton );  return ( *msSingleton );  
}

// The rest of your implementation is following.
...
}


For case 1 just remove _MYLIBExport in the template specialization.

Using a singleton

// Creating the manager. This may only be called once!
new MyManager();

// Obtaining a reference to the manager instance
MyManager& mgr = MyManager::getSingleton();

// Obtaining a pointer to the manager instance
MyManager* pMgr = MyManager::getSingletonPtr();

Note: You may call the Singleton constructor only once. Calling it more often will result in a runtime exception.
There is another semantical difference between getSingleton() and getSingletonPtr(): If the constructor is not called beforehand getSingletonPtr() will return a NULL-Pointer and getSingleton() will throw a runtime exception. So it is probably better to use getSingleton() most of the time, even though it is slightly slower. But you get a clearer response when you set something up wrongly.

Some Links:

Ogre's Singleton Method from 'Game Programming Gems' by Scott Bilas

Huston Design Patterns

Gamedev.net

CodeProject.com


A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | 0-9


Alias: Singleton