IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Singleton en C++


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre �clair�

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Par d�faut Singleton en C++
    Bonjour,

    Je me suis toujours demande (dans un contexte monothread) pourquoi, pour �crire un singleton Widget, on ne fait g�n�ralement pas :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    static Widget& instance()
    {
      static Widget w;
      return w;
    }
    ou bien :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    static Widget& instance()
    {
      static Widget* w = new Widget();
      return *w;
    }

    plut�t qu'utiliser un membre static de la classe Widget :

    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
     
    class Widget
    {
    public:
    ...
     
    static Widget& instance()
    {
      if (!w)
      {
        w = new Widget;
      }
      return *w;
    }
    ...
     
    private:
    static Widget* w;
    };
     
    Widget* Widget::w = 0;
    Ce qui est qd m�me plus long � �crire ...

  2. #2
    R�dacteur
    Avatar de farscape
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par d�faut
    salut,
    dans ton cas tu n'as besoin apparemment que d'une fonction globale ,
    mais si ton singleton propose d'autres services comme la lib�ration de la ressource allou�e, dans ce cas une classe est plus pratique qu'une fonction globale.
    la deuxi�me forme d'allocation de ta ressource peut �tre obligatoire si elle a besoin d'un contexte pr�cis pour �tre instanci�e. (d�pendance avec une autre ressource de l'application).
    donc �a depend de la ressource a partager ,si elle est autonome ou non,
    autre point avec des outils comme intellisense (visual c++) je pr�f�re passer par une classe c'est plus pratique a l'utilisation mais plus long a �crire...

  3. #3
    Membre Expert

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 49
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - Op�rateur de t�l�communications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par d�faut
    Citation Envoy� par vandamme Voir le message
    Bonjour,

    Je me suis toujours demande (dans un contexte monothread) pourquoi, pour �crire un singleton Widget, on ne fait g�n�ralement pas :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    static Widget& instance()
    {
      static Widget w;
      return w;
    }
    C'est le singleton de Meyer.

    Citation Envoy� par vandamme Voir le message
    ou bien :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    static Widget& instance()
    {
      static Widget* w = new Widget();
      return *w;
    }
    Ca, c'est une des formes canoniques.

    Citation Envoy� par vandamme Voir le message
    plut�t qu'utiliser un membre static de la classe Widget :

    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
     
    class Widget
    {
    public:
    ...
     
    static Widget& instance()
    {
      if (!w)
      {
        w = new Widget;
      }
      return *w;
    }
    ...
     
    private:
    static Widget* w;
    };
     
    Widget* Widget::w = 0;
    Ce qui est qd m�me plus long � �crire ...
    Et �a, c'est le singleton tel qu'il est pr�sent� dans le GoF95 - la forme canonique de base.

    Chacune des impl�mentations a sa sp�cificit� (les deux formes canoniques sont �quivalentes, mais le destructeur de Widget n'est pas appel�. Le destructeur du singleton de Meyer est appel�, mais il est difficile voire impossible de savoir quand).

    Ensuite, le choix de l'impl�mentation d�pends du projet sur lequel tu travailles. La question de savoir quelle est la forme la plus facile a d�finir n'a pas v�ritablement d'int�r�t, puisque la bonne r�ponse � cette question d�pends de l'environnement dans lequel le singleton est int�gr�.
    [FAQ des forums][FAQ D�veloppement 2D, 3D et Jeux][Si vous ne savez pas ou vous en �tes...]
    Essayez d'�crire clairement (c'est � dire avec des mots fran�ais complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Caf�. C'est d�pass� tout �a.
    Et si vous �tes sages, vous aurez peut �tre vous aussi la chance de passer � la t�l�. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #4
    Membre �m�rite Avatar de valefor
    Profil pro
    Inscrit en
    D�cembre 2006
    Messages
    711
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2006
    Messages : 711
    Par d�faut
    Anecdote :

    Avec une vieille impl�mentation de gcc, sous Solaris, j'ai eu un probl�me un jour avec ces singletons.

    On faisait un chargement dynamique de biblioth�que.
    De cette biblioth�que on r�cup�rait un singleton.
    On d�chargeait la biblioth�que.
    On arr�tait le programme et paf segv (que l'on n'a pas vu dessuite, on a cru pendant longtemps que tout fonctionnait bien).

    Le probl�me venait que le destructeur du singleton �tait appel� apr�s d�chargement de la lib.

    Avec les versions plus r�centes de gcc le probl�me a �t� r�solu.

  5. #5
    screetch
    Invit�(e)
    Par d�faut
    en quoi une nouvelle version de gcc resout le probleme ?

  6. #6
    Membre �m�rite Avatar de valefor
    Profil pro
    Inscrit en
    D�cembre 2006
    Messages
    711
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2006
    Messages : 711
    Par d�faut
    Elle r�solvait le probl�me au niveau des atexit ou un truc comme cela... l'ordre dans le quel les fonctions de destruction �taient enregistr�es tenait compte du d�chargement des biblioth�ques :
    Avant tout les destructeurs �taient enregistr�s � la fin du programme.
    Apr�s, je ne sais plus comment cela marchait mais il n'y avait plus le probl�me.

  7. #7
    Membre chevronn�
    Inscrit en
    Novembre 2006
    Messages
    362
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par d�faut
    Bonjour,

    Je trouve vos r�ponses (Farscape et Emmanuel Deloget) assez mesur�es, il me semble que l'on n'a pas vraiment le choix.

    Il me semble que, si l'on veut g�rer l'ordre de destruction des singletons, nous sommes "forc�s" d'utiliser un
    plut�t qu'un
    ,
    cf la FAQ ici.

    Du coup, ce serait une entorse � la segmentation des responsabilit�s du code de ne pas g�rer la d�sallocation du pointeur au m�me endroit que son allocation, c'est � dire dans un objet singleton.

    C'est vrai que si on fait diff�remment, on n'est pas certain que cela se passe mal : il se peut qu'au cours de la dur�e de vie du projet, personne n'ajoute jamais aucun autre singleton, ou que les nouveaux singletons ne d�pendent jamais des anciens pour leurs construction ou leur destruction.

    Mais cela me semble �tre du m�me ordre que pas mal d'autres risques que l'on ne prend pas : il se peut que si l'on n'initialise pas des variables ou si l'on n'alloue pas de la m�moire avant de s'en servir, on n'obtienne jamais de crash ni de fonctionnement aberrant. Et pourtant on ne fait jamais d'entorse � ces r�gles, m�me quand on est sur et certain que cela se passera bien.

    Du coup, je me dis qu'il y a quelque chose que j'ai mal compris.
    Pourriez-vous m'�clairer ?
    Merci par avance

  8. #8
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,

    C'est tout l'avantage de passer par une classe qui contient un pointeur vers l'�l�ment statique

    A partir du moment o� ton pointeur est encapsul�, rien ne t'emp�che de cr�er des m�thodes qui renverront une r�f�rence sur l'instance plut�t qu'un pointeur sur celle-ci...

    En effet, tu peux tout aussi bien bien avoir un code proche de
    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
    class Singleton
    {
        public:
            static Singleton& getInstance()
            {
                 if(!instance)
                     instance= new Singleton;
                 return *instance;
            }
            static void freeInstance()
            {
                delete instance;
                instance = NULL;
            }
        private:
            static Singleton *instance;
    };
    que de
    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
    class Singleton
    {
        public:
            static Singleton* getInstance()
            {
                 if(!instance)
                     instance= new Singleton;
                 return instance;
            }
            static void freeInstance()
            {
                delete instance;
                instance = NULL;
            }
        private:
            static Singleton *instance;
    };
    et, si ton singleton d�pend d'un autre singleton, rien ne t'emp�cherait m�me d'�crire un code proche de
    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
    27
    28
    29
    class Singleton
    {
        public:
            static Singleton& getInstance()
            {
                 /* Singleton2::getInstance() renvoie également une référence
                  * sur l'instance ;)
                  */
     
                 if(!instance)
                     instance= new Singleton(Singleton2::getInstance());
     
                 /* ou, de manière plus lisible: */
                 if(!instance)
                 {
                     Singleton2 s2=Singleton2::getInstance();
                     instance = new Singelton(s2);
                 }
                 /* renvoi de la référence sur l'instance */
                 return *instance;
            }
            static void freeInstance()
            {
                delete instance;
                instance = NULL;
            }
        private:
            static Singleton *instance;
    };
    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

  9. #9
    Membre �clair�

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Par d�faut
    Et bien merci beaucoup pour vos r�ponses constructives.

  10. #10
    Membre Expert

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 49
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - Op�rateur de t�l�communications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par d�faut
    Pour ma part, et je sais que je vais en surprendre plus d'un, je ne vois pas d'int�r�t � vouloir absolument que le singleton soit d�truit � un moment quelconque du programme (y compris une fois que main() a fini de s'ex�cuter). Nous sommes dans un monde simplifi�, ou l'OS prends en charge l'unload do process et termine toutes les ressources allou�es par ce process. De fait, la m�moire, les fichiers ouverts, etc sont correctement lib�r�/ferm�/etc � la fin du programme.

    Certes, on peut toujours me r�pondre "�a fait un resource leak ! ". Et bien non: puisque le singleton est cens� �tre valide � partir du moment ou il est instanci� et jusqu'� la fin du programme (c'est � dire, dans un sens, jusqu'� ce que le dernier destructeur de la derni�re instance qui a une dur�e de vie statique ait fini de s'ex�cuter), quel leak est-ce que je cr�e si je ne le lib�re pas en quittant ? Aucun, puisque sit�t apr�s l'ex�cution du destructeur du singleton, on est cens� redonner la main � l'OS pour qu'il fasse le clean up.

    En fait, si on donne � l'utilisateur la possibilit� de d�truire le singleton quand il le souhaite, on prends le risque de l'autoriser � l'utiliser apr�s qu'il ait �t� d�truit - ce qui est bien plus ennuyeux que de ne pas le d�truire au niveau de la maintenance du code.

    J'en entends d�j� qui me hurlent "mais un utilisateur lambda ne ferais pas �a!". Certes. C'est possible. Le m�me utilisateur lambda ne d�clarera pas deux instances de la m�me classe si vous lui dites qu'il n'en a pas le droit. Puisque vous vous substituez � son intelligence en interdisant la cr�ation d'une seconde instance de votre classe, pourquoi lui permettre de la d�truire apr�s ? Ca n'est pas tr�s consistant
    [FAQ des forums][FAQ D�veloppement 2D, 3D et Jeux][Si vous ne savez pas ou vous en �tes...]
    Essayez d'�crire clairement (c'est � dire avec des mots fran�ais complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Caf�. C'est d�pass� tout �a.
    Et si vous �tes sages, vous aurez peut �tre vous aussi la chance de passer � la t�l�. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [Servlet]Singleton & cache
    Par lucimast dans le forum Servlets/JSP
    R�ponses: 4
    Dernier message: 15/12/2004, 16h36
  2. Singleton h�ritable ?
    Par rolkA dans le forum C++
    R�ponses: 10
    Dernier message: 11/12/2004, 16h22
  3. [D�butant] pattern singleton
    Par SirDarken dans le forum D�buter avec Java
    R�ponses: 22
    Dernier message: 11/12/2004, 01h55
  4. Mutiple row in singleton select ????? [Important, merci]
    Par SkyDev dans le forum Bases de donn�es
    R�ponses: 6
    Dernier message: 20/04/2004, 14h02
  5. [debutant]Singleton
    Par bafman dans le forum Langage SQL
    R�ponses: 6
    Dernier message: 13/01/2004, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo