Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
722 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [c++] class singleton

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

[c++] class singleton

n°812946
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-08-2004 à 18:00:30  profilanswer
 

Je decouvre qu'il existait une classe de base pour faire un singleton, je croyais que c'etait pas possible... à cause en particulier du static instance.
 

Code :
  1. template< typename X >
  2. struct singleton
  3. {
  4. inline static X* instancier();
  5. protected:
  6. singleton() {};
  7. virtual ~singleton() {};
  8. singleton( const singleton& ) {};
  9. singleton& operator=( const singleton& ) {};
  10. private:
  11. static X* instance;
  12. };
  13. template< typename X >
  14. X* singleton<X>::instance( 0 );
  15. template< typename X >
  16. X* singleton<X>::instancier()
  17. {
  18. if( instance == 0 )
  19. instance = new X;
  20. return instance;
  21. }
  22. // template de classe derivée
  23. class X : public singleton<X> ...


 
La classe est semble t il incomplete, mais ca donne une idée.


Message édité par xterminhate le 04-08-2004 à 12:16:23

---------------
Cordialement, Xterm-in'Hate...
mood
Publicité
Posté le 02-08-2004 à 18:00:30  profilanswer
 

n°813156
blackgodde​ss
vive le troll !
Posté le 03-08-2004 à 09:14:30  profilanswer
 

Bien :jap:
 
Aucune lib n'en fournit une ?


---------------
-( BlackGoddess )-
n°813221
Taz
bisounours-codeur
Posté le 03-08-2004 à 10:27:56  profilanswer
 

si. merde j'ai oublié de répondre hier soir. utilise un truc genre smart pointer pour éviter tout fuite.

n°813289
blackgodde​ss
vive le troll !
Posté le 03-08-2004 à 11:04:12  profilanswer
 

boost::scoped_ptr serait approprié ?


---------------
-( BlackGoddess )-
n°813316
Taz
bisounours-codeur
Posté le 03-08-2004 à 11:13:30  profilanswer
 

non. un simple std::auto_ptr suffit je pense

n°814052
xterminhat​e
Si vis pacem, para bellum.
Posté le 03-08-2004 à 19:06:23  profilanswer
 

Ca permettrait de ne pas appeler explicitement un methode de destruction, c'est bien ca ?


---------------
Cordialement, Xterm-in'Hate...
n°814077
Taz
bisounours-codeur
Posté le 03-08-2004 à 19:25:09  profilanswer
 

oui. fais le test, tu verras

n°814671
xterminhat​e
Si vis pacem, para bellum.
Posté le 04-08-2004 à 12:19:50  profilanswer
 

En ré-ecrivant le membre "static auto_ptr<X> instance", est ce vraiment compatible de la foncion membre instancier() ( copie de autoptr à la ligne return instance ? ).


---------------
Cordialement, Xterm-in'Hate...
n°814675
Taz
bisounours-codeur
Posté le 04-08-2004 à 12:21:35  profilanswer
 

heink ?

n°814690
xterminhat​e
Si vis pacem, para bellum.
Posté le 04-08-2004 à 12:40:55  profilanswer
 

Au temps pour moi, j'ai forcé sur le rouge à midi!  :pt1cable:  
 

Code :
  1. template< typename X >
  2. struct singleton
  3. {
  4. inline static X* instancier();
  5. protected:
  6. singleton() {};
  7. virtual ~singleton() {};
  8. singleton( const singleton& ) {};
  9. singleton& operator=( const singleton& ) {};
  10. private:
  11. static std::auto_ptr<X> instance;
  12. };
  13. template< typename X >
  14. std::auto_ptr<X> singleton<X>::instance( 0 );
  15. template< typename X >
  16. X* singleton<X>::instancier()
  17. {
  18. if( instance.get() == 0 )
  19. instance.reset( new X );
  20. return instance.get();
  21. }


 
Je suis pas trop sur, je maitrise pas l'auto_ptr.


Message édité par xterminhate le 04-08-2004 à 12:41:08

---------------
Cordialement, Xterm-in'Hate...
mood
Publicité
Posté le 04-08-2004 à 12:40:55  profilanswer
 

n°814806
Taz
bisounours-codeur
Posté le 04-08-2004 à 14:14:33  profilanswer
 

vous avez vraiment le chic pour faire compliquer. ni membre statique ni rien, juste un static dans une fonction et directement initialisé.|

n°814892
blackgodde​ss
vive le troll !
Posté le 04-08-2004 à 14:41:54  profilanswer
 

Code :
  1. #include <memory>
  2. template< typename X >
  3. struct singleton
  4. {
  5.     inline static X& get()
  6. {
  7.  static std::auto_ptr<X> obj;
  8.  if(!obj.get())
  9.   obj.reset(new X);
  10.  return *obj;
  11. }
  12. };
  13. class X : public singleton<X> ...


 
comme ca alors ?


---------------
-( BlackGoddess )-
n°814932
Taz
bisounours-codeur
Posté le 04-08-2004 à 14:54:31  profilanswer
 

pourquoi tu veux pas initialiser ton obj ?

n°814939
mynab
Posté le 04-08-2004 à 14:58:24  profilanswer
 

non comme ca:
 

Code :
  1. template<typename X> class singleton
  2. {
  3. public:
  4.     static X& get()
  5. {
  6.  static X obj;
  7.  return obj;
  8. }
  9. protected:
  10. singleton() {}
  11. };
  12. class X : public singleton<X>
  13. {
  14. protected:
  15. X() {}
  16. };


 
Tu n'as pas besoin de mettre inline a partir du moment ou la methode est implemetee dans la definition de la classe...


Message édité par mynab le 04-08-2004 à 15:00:02
n°814990
SoWhatIn22
Posté le 04-08-2004 à 15:55:26  profilanswer
 

note que je ne sais pas dans quelle mesure c'est vrai, mais le fait d'utiliser une instance statique et no pas un pointeur peut poser de sérieux problèmes:
 
1. tu dois avoir une initialisation indépendante de toutes les autres données de ton système puisque tu ne peux pas présupposer de l'ordre de l'initialisation des varaiables statiques et des varaiables globales
 
2. dans le cas où ce code se retrouve dans une bibliothèque dynamique contenant du code C++, les objets statiques sont instanciés sans que le constructeur soit appelé si le programme appelant a été écrit/compilé en C (pb bien connu par ceux qui écrivent des extensions pour Python en C++). Dans ce cas, il vaut mieux passer par un pointeur initialisé à 0 et créer l'instance dynamiquement au premier appel.

n°815002
blackgodde​ss
vive le troll !
Posté le 04-08-2004 à 16:03:54  profilanswer
 

bin dans un cas l'objet sera créé au lancement du programme, dans l'autre cas à la 1ere demande de l'objet ... je ne sais pas si c'est important ...


---------------
-( BlackGoddess )-
n°815009
Taz
bisounours-codeur
Posté le 04-08-2004 à 16:07:06  profilanswer
 

dans tous les cas, j'aime pas trop les singleton en C/C++, je préfère les implémentations dans les langages qui permettent les weakref, genre python, je me sens plus tranquille quand on me réclame un truc, je file une weakref et voilà

n°815022
Taz
bisounours-codeur
Posté le 04-08-2004 à 16:20:27  profilanswer
 

d'ailleurs j'aime bien aussi le borg-shared-state pattern

n°815026
SoWhatIn22
Posté le 04-08-2004 à 16:24:10  profilanswer
 

google(borg-shared-state pattern) => 'did not match any documents'. c'est quoi donc ce pattern?

n°815028
SoWhatIn22
Posté le 04-08-2004 à 16:26:54  profilanswer
 

BlackGoddess a écrit :

bin dans un cas l'objet sera créé au lancement du programme, dans l'autre cas à la 1ere demande de l'objet ... je ne sais pas si c'est important ...


ça peut l'être si la construction de cet objet nécessite la collaboration d'autres objets, ou dans le cas (2) que j'ai indiqué; par contre pour l'utilisateur de cette méthode peut importe.
Mais quand on choisit une implémentation plutôt qu'une autre, c'est bien de savoir pourquoi.

n°815047
Taz
bisounours-codeur
Posté le 04-08-2004 à 16:46:31  profilanswer
 
n°815331
xterminhat​e
Si vis pacem, para bellum.
Posté le 04-08-2004 à 22:09:52  profilanswer
 

mynab a écrit :

non comme ca:
 

Code :
  1. template<typename X> class singleton
  2. {
  3. public:
  4.     static X& get()
  5. {
  6.  static X obj;
  7.  return obj;
  8. }
  9. protected:
  10. singleton() {}
  11. };
  12. class X : public singleton<X>
  13. {
  14. protected:
  15. X() {}
  16. };


 
Tu n'as pas besoin de mettre inline a partir du moment ou la methode est implemetee dans la definition de la classe...


 
Quelle simplification ! Par contre, est il tjs possible de masquer le constructeur de la classe dérivée (protected) en utilisant ce template de singleton ?


---------------
Cordialement, Xterm-in'Hate...
n°815743
mynab
Posté le 05-08-2004 à 12:07:50  profilanswer
 

Non tu es oblige de remettre le constructeur dans la classe derivee... Sinon quelqu'un pourra construire un objet de type X. Mais tu n'as pas besoin de deriver la classe si tu n'as rien a y ajouter. Tu peux direcement appeler: singleton<int>::get() par exemple. Ou pour faire plus simple tu peux faire un typedef sur singleton<int>.


Message édité par mynab le 05-08-2004 à 12:08:52
n°815869
blackgodde​ss
vive le troll !
Posté le 05-08-2004 à 13:58:26  profilanswer
 

il y a un problème par contre si 2 classes utilisent singleton<int> indépendemment, en effet elles travailleraient sur la meme variable...


---------------
-( BlackGoddess )-
n°815949
Taz
bisounours-codeur
Posté le 05-08-2004 à 14:48:47  profilanswer
 

faites une factory

n°816005
blackgodde​ss
vive le troll !
Posté le 05-08-2004 à 15:15:37  profilanswer
 

tu saurais ou trouver de la doc expliquant ce genre de design ?


---------------
-( BlackGoddess )-
n°816037
mynab
Posté le 05-08-2004 à 15:30:05  profilanswer
 

BlackGoddess a écrit :

il y a un problème par contre si 2 classes utilisent singleton<int> indépendemment, en effet elles travailleraient sur la meme variable...


 
ben c'est pas le but d'un singleton?

n°816047
Taz
bisounours-codeur
Posté le 05-08-2004 à 15:39:32  profilanswer
 

cherche design pattern sur le forum et google
cherche factory singleton ensuite

n°816052
Taz
bisounours-codeur
Posté le 05-08-2004 à 15:45:55  profilanswer
 

je crois que y a un exemple dans TIC++ de B Eckel

n°816216
xterminhat​e
Si vis pacem, para bellum.
Posté le 05-08-2004 à 18:27:46  profilanswer
 

Ce que je voulais dire...
 

Code :
  1. template<typename X> class singleton 
  2. public:
  3. static X& get()
  4. {
  5. static X obj;
  6. return obj;
  7. }
  8. protected:
  9. singleton() {}
  10. }; 
  11. class X : public singleton<X>
  12. {
  13. protected:
  14. X() {}
  15. };
  16. int main()
  17. {
  18.   X& x( X::get() );
  19. }


 
ne compile pas :  
 
In static member function `static X& singleton<X>::get() [with X = X]' `X::X()' is protected within this context... blabla.


---------------
Cordialement, Xterm-in'Hate...
n°816220
Taz
bisounours-codeur
Posté le 05-08-2004 à 18:41:23  profilanswer
 

colle un friend

n°816291
xterminhat​e
Si vis pacem, para bellum.
Posté le 05-08-2004 à 21:01:05  profilanswer
 

Ok. Mais, ajouter friend singleton<X> dans la déclaration de X est un peu contraignant.


---------------
Cordialement, Xterm-in'Hate...
n°816294
schnapsman​n
Zaford Beeblefect
Posté le 05-08-2004 à 21:02:16  profilanswer
 

xterminhate a écrit :

Ok. Mais, ajouter friend singleton<X> dans la déclaration de X est un peu contraignant.


 
non c'est le contraire :D
 

Code :
  1. template<typename X> class singleton 
  2. {
  3. friend class X;
  4. public:
  5. static X& get()
  6. {
  7. static X obj;
  8. return obj;
  9. }
  10. protected:
  11. singleton() {}
  12. };


Message édité par schnapsmann le 05-08-2004 à 21:05:00

---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
n°816302
Taz
bisounours-codeur
Posté le 05-08-2004 à 21:09:33  profilanswer
 

ben ça sert à rien ça, puisque X a déjà accès :o
 
friend class singleton<X> est ok
 
à toi de savoir ce que tu fais

n°816303
xterminhat​e
Si vis pacem, para bellum.
Posté le 05-08-2004 à 21:10:12  profilanswer
 

schnapsmann a écrit :

non c'est le contraire :D
 

Code :
  1. template<typename X> class singleton 
  2. {
  3. friend class X;
  4. public:
  5. static X& get()
  6. {
  7. static X obj;
  8. return obj;
  9. }
  10. protected:
  11. singleton() {}
  12. };



 
Etonnant, tu as quel compilateur ?


---------------
Cordialement, Xterm-in'Hate...
n°816306
schnapsman​n
Zaford Beeblefect
Posté le 05-08-2004 à 21:11:55  profilanswer
 

merde je voyais private et non protected là


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
n°816341
mynab
Posté le 05-08-2004 à 22:36:03  profilanswer
 

xterminhate a écrit :

Ce que je voulais dire...
 

Code :
  1. ...
  2. int main()
  3. {
  4.   X& x( X::get() );
  5. }


 
ne compile pas :  
 
In static member function `static X& singleton<X>::get() [with X = X]' `X::X()' is protected within this context... blabla.


 
Ben c'est normal... je ne comprends pas trop ce que tu veux faire avec l'appel que tu fais dans le main...
 
X derive de singleton<> et est donc un singleton. Tu essaies donc de creer une deuxieme instance x de ton singleton. C'est normal que ca ne compile pas puisque en faisant un singleton c'est justement de que tu demandes au compilo: t'interdire de creer plusieurs instances de ton singleton!
 
Si tu veux creer un singleton sur la classe X alors il faut faire:
 

Code :
  1. class X
  2. {
  3.     friend class singleton<X>;
  4. protected:
  5.     X() { // ce que tu veux }
  6. };


 
et apres tu accedes a singleton<X> et voila!


Message édité par mynab le 05-08-2004 à 22:36:38
n°816394
xterminhat​e
Si vis pacem, para bellum.
Posté le 06-08-2004 à 07:29:12  profilanswer
 

mynab a écrit :

Ben c'est normal... je ne comprends pas trop ce que tu veux faire avec l'appel que tu fais dans le main...


 
Dans le main, je souhaite acceder à l'instance unique de mon singleton de X. C'est un cas d'utilisation parmi tant d'autres. Le but etait bien de faire un modèle de singleton utilisable.
 
A mon sens, le rôle de singleton<X>::get() est de retourner une référence unique. Donc l'appel dans le main, ne multiplie pas les instances de mon singleton de X! Corriges moi si je fais une erreur.
 
D'ailleurs, appeler x::get ou singleton<x>::get revient au même.
 

Code :
  1. int main()
  2. {
  3. {
  4. X& y1( X::get() );
  5. }
  6. X& y2( X::get() );
  7. X& y3( X::get() );
  8. X& y4( X::get() );
  9. X& y5( X::get() );
  10. X& x1( singleton<X>::get() );
  11. X& x2( singleton<X>::get() );
  12. {
  13. X& x3( singleton<X>::get() );
  14. }
  15. X& x4( singleton<X>::get() );
  16. // &y1 = &y2 = &y3 = ... = &x1 = & x2 = ....
  17. }


 

mynab a écrit :


X derive de singleton<> et est donc un singleton. Tu essaies donc de creer une deuxieme instance x de ton singleton. C'est normal que ca ne compile pas puisque en faisant un singleton c'est justement de que tu demandes au compilo: t'interdire de creer plusieurs instances de ton singleton!


 
Non. Je ne vois pas ce qui est normal. Comment arriverais tu à utiliser le modèle que tu m as donné sans ajouter le friend ? [:airforceone]  
 
Merci.


Message édité par xterminhate le 06-08-2004 à 07:30:11

---------------
Cordialement, Xterm-in'Hate...
n°898345
tanguy
Posté le 14-11-2004 à 18:30:22  profilanswer
 

Voila mon singleton, dites moi ce que vous en pensez:
 

Code :
  1. #ifndef SINGLETON_H
  2. #define SINGLETON_H
  3. #include <memory>
  4. template<typename T>
  5. class Singleton {
  6. public:
  7. static T & getInstance() {
  8.  static std::auto_ptr<T> instance;
  9.  if (!instance.get()) {
  10.   instance.reset(new T);
  11.  }
  12.  return *instance.get();
  13.  /* Sans auto_ptr donc fuite memoire.
  14.  static T * instance;
  15.  if (!instance) {
  16.   instance = new T;
  17.  }
  18.  return *instance;
  19.  */
  20. }
  21. protected:
  22. Singleton() { }
  23. virtual ~Singleton() { }
  24. Singleton(const Singleton & ) { }
  25. Singleton & operator=(const Singleton & ) { }
  26. };
  27. #endif //SINGLETON_H


 
Et un exemple d'utilisation de la classe:

Code :
  1. #include "Singleton.h"
  2. #include <iostream>
  3. using namespace std;
  4. class Toto : public Singleton<Toto> {
  5. friend class Singleton<Toto>;
  6. public:
  7. void sayHello() const {
  8.  cout << "Hello World!" << endl;
  9. }
  10. protected:
  11. Toto() {
  12.  _counter += 1;
  13.  cout << "Initialization: " << _counter << endl;
  14. }
  15. private:
  16. static int _counter;
  17. };
  18. int Toto::_counter = 0;
  19. int main() {
  20. Toto & toto1 = Toto::getInstance();
  21. toto1.sayHello();
  22. Toto & toto2 = Toto::getInstance();
  23. toto2.sayHello();
  24. }


 
J'ai compile avec la ligne suivante:
g++ -g -ansi -Wall -pedantic main.cpp
 
Et valgrind me dit:


valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out
==7364== Memcheck, a memory error detector for x86-linux.
==7364== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==7364== Using valgrind-2.3.0.CVS, a program supervision framework for x86-linux.
==7364== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==7364== For more details, rerun with: -v
==7364==
Initialization: 1
Hello World!
Hello World!
==7364==
==7364== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 1)
==7364== malloc/free: in use at exit: 0 bytes in 0 blocks.
==7364== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.
==7364== For counts of detected errors, rerun with: -v
==7364== No malloc'd blocks -- no leaks are possible.


 
Et si je n'utilise pas auto_ptr (le code en commentaire), valgrind me dit:


valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out
==7371== Memcheck, a memory error detector for x86-linux.
==7371== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==7371== Using valgrind-2.3.0.CVS, a program supervision framework for x86-linux.
==7371== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==7371== For more details, rerun with: -v
==7371==
Initialization: 1
Hello World!
Hello World!
==7371==
==7371== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 1)
==7371== malloc/free: in use at exit: 4 bytes in 1 blocks.
==7371== malloc/free: 1 allocs, 0 frees, 4 bytes allocated.
==7371== For counts of detected errors, rerun with: -v
==7371== searching for pointers to 1 not-freed blocks.
==7371== checked 2227148 bytes.
==7371==
==7371== 4 bytes in 1 blocks are still reachable in loss record 1 of 1
==7371==    at 0x1B904730: operator new(unsigned) (vg_replace_malloc.c:132)
==7371==    by 0x80489D6: Singleton<Toto>::getInstance() (Singleton.h:24)
==7371==    by 0x80488F0: main (main.cpp:29)
==7371==
==7371== LEAK SUMMARY:
==7371==    definitely lost: 0 bytes in 0 blocks.
==7371==    possibly lost:   0 bytes in 0 blocks.
==7371==    still reachable: 4 bytes in 1 blocks.
==7371==         suppressed: 0 bytes in 0 blocks.


Message édité par tanguy le 14-11-2004 à 18:33:19
n°898417
xterminhat​e
Si vis pacem, para bellum.
Posté le 14-11-2004 à 20:53:04  profilanswer
 

Ce modèle ci ne convenait pas ?

Code :
  1. template< typename X >
  2. struct singleton 
  3. static X& instancier()
  4. {
  5.  static X obj;
  6.  return obj;
  7. }
  8. virtual ~singleton() {}
  9. protected:
  10. singleton() {}
  11. singleton( const singleton& ) {}
  12. singleton& operator=( const singleton& ) {}
  13. };


---------------
Cordialement, Xterm-in'Hate...
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [c++] class singleton

 

Sujets relatifs
[css] class, id et heritageRécupérer via Javascript une propriété d'une class CSS non utilisé
[JAVA] Inner class et accès aux membres protected --> compiler bug ?Propriétés 'class' et 'div'
Probleme de class avec GDComen séparer l'interface graphik et les méthod en diférentes class
[Applet] load : class not foundInfos sur les fichiers .class
[Java] Retrouver le code java a partir des .class ?Eclipse et Export Jar : Failed to load Main-Class ....
Plus de sujets relatifs à : [c++] class singleton


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR