Bonjour,
Comment créer une classe singleton en C++?
Est ce qu'il suffit de déclarer son constructeur et son destructeur comme étant "private"?
Bonjour,
Comment créer une classe singleton en C++?
Est ce qu'il suffit de déclarer son constructeur et son destructeur comme étant "private"?
Après une petite recherche sur Google avec les mots clés 'singletion' et 'C++', je susi tombé là-dessus :
http://tfc.duke.free.fr/coding/singleton.html
Une recherche sur la FAQ t'aurais également bien aidé : FAQ : Singleton.
Salut,
Non, ces deux points ne sont qu'une partie de la réponse, et rendent ta classe tout à fait inutile si tu en reste là...
En effet, le constructeur est appelé chaque fois qu'il s'agit de créer une instance (un objet du type) de la classe, et le destructeur est appelé chaque fois qu'une instance (un objet du type) de la classe est détruit(e).
En tu plaçant le constructeur et le destructeur dans l'accessibilité privée, tu indique que seules les fonctions de la classe peuvent y accéder...
Si tu t'arrête là, tu en arrive à une situation ubuesque dans laquelle il te faut une instance de la classe pour accéder à une des fonctions de celle-ci qui pourra créer l'instance de la classe que tu souhaite obtenir, alors qu'il t'est justement impossible d'obtenir cette première instance(tant mieux si tu es perdu, ca te montrera d'autant mieux le problème
)
Ce qu'il faut donc, c'est de déclarer une fonction qui fasse partie de la classe (pour pouvoir accéder au constructeur), mais qui puisse être indépendante de toute instance de la classe (parce qu'il faut bien rompre le cercle viscieux).
En conception, on parle de fonctions de classes, par opposition aux fonctions d'instances.
En C++, cela passe par la création dans la classe d'une fonction déclarée static qui renverra une instance de la classe et que nous pourrions nommer, faisons simple, instance()
Cependant, nous n'avons encore qu'une demi solution.
En effet, nous pouvons maintenant invoquer la fonction instance qui peut invoquer le constructeur alors que nous n'avons encore aucun objet de ce type, mais il faut maintenant s'assurer que ce sera toujours la même instance qui sera renvoyée, et ce, quel que soit l'endroit ou le nombre de fois que nous appellerons la fonction instance()...
Deux solutions sont alors envisageables:
La première consiste "simplement" à créer une instance de la classe qui sera partagée par tous les appels de notre fonction instance()
Pour ce faire, nous déclarons "simplement" un objet du type de notre classe comme statique dans la fonction, et nous renvoyons une référence dessus.
Cela nous donnera une classe proche de
Soit nous décidons que l'instance qui nous intéresse doit être un membre à part entière de la classe qui devra... être partagé par... l'ensemble des instances de la classe (oula... à lire cela, on pourrait devenir chêvre
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 class MySingleton { public: /* la fonction qui permet d'être singleton */ static MySingleton & instance() { static MySingleton inst; return inst; } /* les fonctions qui nécessitent une instance pour fonctionner */ private: MySingleton(){} ~MySingleton(){/*...*/} };)
Il s'agira alors de déclarer un membre de la classe comme étant static
Mais, comme il est difficile de placer dans une structure un membre dont le type est cette structure, il faudra utiliser un pointeur, que l'on veillera à initialiser correctement.
L'allocation dynamique de la mémoire se fera la première fois qu'une instance sera demandée, et l'on peut envisager de décider de la détruire à l'aide d'une fonction (qui ne doit pas nécessiter d'instance) que nous pourrions nommer destroy().
à ce moment là, il faudra envisager un code proche de
Ce ne sera qu'une fois que nous aurons pris ces différentes mesures que nous pourrons estimer avoir correctement brisé la "quadrature du cercle"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 class MySingleton { public: /* la fonction qui permet d'être singleton */ static MySingleton & instance() { if(!inst) inst = new MySingleton(); return *inst; } /* la fonction qui détruit l'instance */ static void destroy() { delete inst; inst = 0; } /* les fonctions qui nécessitent une instance pour fonctionner */ private: MySingleton(){} ~MySingleton(){/*...*/} static MySingleton * inst; }; /* !!! il est important d'initialiser correctement inst, dans un (et un seul) * fichier d'implémentation (*.cpp) sous la forme de */ MySingleton * MySingleton::inst = 0;![]()
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Et sinon, juste pour info, un article sympa sur l'implémentation de singletons:
Creating Dynamic Singletons & the Loki Library
Trade-offs in implementing the Singleton design pattern
http://www.ddj.com/cpp/184401943
http://loki-lib.sourceforge.net/inde...tern.Singleton
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Ma vision fortement résumée des singletons : http://www.developpez.net/forums/d61...n/#post3625543
(<= Dans un contexte MT (qui est le mien), il n'existe aucun moyen d'avoir une construction paresseuse de singleton qui soit thread-safe en C++98/03 ; et de plus j'ai régulièrement besoin de passer des paramètres à leur construction)
NB: ACE et loki ont les deux seules solutions par bibliothèque qui ressemblent à peu près à quelque chose. Par expérience, les fichiers squelettes sont bien plus efficaces si on veut du singleton intrusif.
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
Partager