Singleton

From Ogre Wiki

Jump to: navigation, search

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.

Contents

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

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>::ms_Singleton = 0;
MyManager* MyManager::getSingletonPtr(void)
{
    return ms_Singleton;
}
MyManager& MyManager::getSingleton(void)
{  
    assert( ms_Singleton );  return ( *ms_Singleton );  
}

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

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

Personal tools
administration