Intro :
Le Singleton est un patron de conception.
Il est utile lorsque l’on a besoin d’utiliser et d’instancier un seul objet au lieu le passer paramètre après paramètre et fonction par fonction.
En somme il permet d’accéder directement dans tout le programme un objet quelconque (appelé « Singleton »).
Explications / exemples :
Cas sans le Singleton :
// on passe le paramètre fonction après fonction
void une_foncton(Object* obj)
{
une_autre_fonction(obj);
}
// et encore un paramètre de passé...
void une_autre_fonction(Object* obj)
{
std::string sName = obj->getName();
std::cout << sName << std::endl;
}
Cas avec le Singleton :
On accède directement à l’objet sans avoir à le passer paramètre par paramètre :
void une_autre_fonction()
{
Object->getSingleton()->getName();
}
Donc :
// Cette fonction n'est plus utile void une_foncton(Object* obj)
Voici le fichier d’en-tête / d’include :
#ifndef SINGLETON_H
#define SINGLETON_H
#define SAFE_DELETE(p) if (p) { delete (p); (p) = NULL; }
template <typename T>
class Singleton
{
public:
Singleton()
{
assert(!ms_instance);
ms_instance = static_cast<T*>(this);
}
~Singleton () {}
static T* getSingletonPtr()
{
assert(ms_instance);
return ms_instance;
}
static void destroy()
{
SAFE_DELETE(ms_instance);
}
static bool IsCreated()
{
return ms_instance != nullptr;
}
private: // Opération interdite
Singleton(const Singleton<T> &);
Singleton& operator=(const Singleton<T> &);
private:
static T* ms_instance;
};
#endif
Utilisation :
Dans le fichier include : EventManager.h
class EventManager : public Singleton<EventManager>
{
// Suite de votre code...
};
Dans le fichier cpp : EventManager.cpp
on doit mettre tout en haut de ce fichier :
template<> EventManager* Singleton<EventManager>::ms_instance = NULL;
Exemple d’utilisation :
GlobalSystems::GlobalSystems()
{
m_pInputManager = InputManager::getSingletonPtr();
m_pTextAnnouncer = TextAnnouncer::getSingletonPtr();
m_pCameraManager = CameraManager::getSingletonPtr();
m_pConsole = Console::getSingletonPtr();
}
Astuces et conseils :
1 – N’oubliez surtout pas de créer votre objet avant son utilisation en appelant :
new NomDeLaClasse();
sinon vous obtiendrez un bug de pointeur non initialisé ! (segfault)
2 – Utiliser plusieurs macro #define de la sorte :
#define EVENT_MANAGER EventManager->getSingleton()
on utilise cette macro / raccourcis pour appeler une méthode : EVENT_MANAGER->methode()
cela permet de simplifier l’écriture du code…
Résumé :
Le patron de conception Singleton restreint l’instanciation d’une classe à un seul objet.
Il permet de simplifier l’accès global à un objet (par exemple à une classe TextureManager ou EventManager)

