Nous avons récemment abordé ce sujet dans ma classe EECS. Si vous voulez regarder les notes de cours en détail, visitez http://umich.edu/~eecs381/lecture/IdiomsDesPattsCreational.pdf
Il y a deux façons que je connais de créer correctement une classe Singleton.
Première voie:
Implémentez-le de la même manière que vous l'avez dans votre exemple. Quant à la destruction, «les singletons durent généralement pendant la durée de l'exécution du programme; la plupart des systèmes d'exploitation récupèrent la mémoire et la plupart des autres ressources à la fin d'un programme, il y a donc un argument pour ne pas s'inquiéter de cela».
Cependant, il est recommandé de nettoyer à la fin du programme. Par conséquent, vous pouvez le faire avec une classe SingletonDestructor statique auxiliaire et le déclarer comme ami dans votre Singleton.
class Singleton {
public:
static Singleton* get_instance();
// disable copy/move -- this is a Singleton
Singleton(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton& operator=(Singleton&&) = delete;
friend class Singleton_destroyer;
private:
Singleton(); // no one else can create one
~Singleton(); // prevent accidental deletion
static Singleton* ptr;
};
// auxiliary static object for destroying the memory of Singleton
class Singleton_destroyer {
public:
~Singleton_destroyer { delete Singleton::ptr; }
};
Le Singleton_destroyer sera créé au démarrage du programme et "lorsque le programme se termine, tous les objets globaux / statiques sont détruits par le code d'arrêt de la bibliothèque d'exécution (inséré par l'éditeur de liens), donc le_destroyer sera détruit; son destructeur supprimera le Singleton, exécutant son destructeur. "
Deuxième voie
C'est ce qu'on appelle le Meyers Singleton, créé par l'assistant C ++ Scott Meyers. Définissez simplement get_instance () différemment. Maintenant, vous pouvez également vous débarrasser de la variable membre du pointeur.
// public member function
static Singleton& Singleton::get_instance()
{
static Singleton s;
return s;
}
C'est bien car la valeur retournée est par référence et vous pouvez utiliser la .
syntaxe au lieu d' ->
accéder aux variables membres.
"Le compilateur crée automatiquement du code qui crée 's' pour la première fois via la déclaration, pas par la suite, puis supprime l'objet statique à la fin du programme."
Notez également qu'avec le Meyers Singleton, vous "pouvez vous retrouver dans une situation très difficile si les objets dépendent les uns des autres au moment de la terminaison - quand le Singleton disparaît-il par rapport à d'autres objets? Mais pour les applications simples, cela fonctionne très bien".