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

Langage C++ Discussion :

Singleton ou variables statics """global""" ?


Sujet :

Langage C++

  1. #1
    Nouveau membre du Club
    Profil pro
    CIO
    Inscrit en
    Novembre 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : CIO

    Informations forums :
    Inscription : Novembre 2010
    Messages : 6
    Par défaut Singleton ou variables statics """global""" ?
    Bonjour à tous,

    J'ai besoin de récupérer des valeurs dans un fichier texte et les attribuer à des variables.

    Exemple : La touche "A" me permet d'ouvrir une fenêtre mais si je veux, je dois pouvoir changer dans le fichier texte cette touche par une autre.

    Mon idée est la suivante : Je fais un seul fichier de conf, j'y accède en début de programme, je charge tout en mémoire, et quand j'en ai besoin, j'accède aux variables... (Car au final, le fichier en question contiendra bien plus que des raccourcis clavier...)

    J'ai parcouru le net en long en large (et peut être de travers), pour voir les différentes solutions et je crois en avoir trouvé 3 :

    1/ Utiliser les variables globales --> C'est pas propre, sources de conflits, donc à éviter fortement.
    2/ Utiliser des variables statics
    3/ Utiliser un singleton

    Je vais donc creuser la reflexion sur la solution 2 ou 3, mais comment faire pour que mes variables statics, ou mon singleton, soient globales non pas à une classe, mais à l'ensemble de mes classes ?

  2. #2
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Bonjour,

    Citation Envoyé par base-un Voir le message
    comment faire pour que mes variables statics, ou mon singleton, soient globales non pas à une classe, mais à l'ensemble de mes classes ?
    Je ne suis pas sûr de comprendre ton problème.
    Les variables statiques sont certes définies dans une classe, mais ne nécessitent pas qu'elle soit instanciée pour être accessibles.
    Si tu les déclares « publiques » (ou à défaut, leurs accesseurs), elles seront « globales » à tout ce qui connaît la classe à laquelle elles appartiennent.

    Quant au « singleton », c'est un concept qui se modélise en C++ par une classe (avec des propriétés particulières).
    Donc de la même manière…

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Citation Envoyé par base-un Voir le message
    Je vais donc creuser la reflexion sur la solution 2 ou 3, mais comment faire pour que mes variables statics, ou mon singleton, soient globales non pas à une classe, mais à l'ensemble de mes classes ?
    La déclarer en public static ne suffit-il pas?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    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
    Pattern monostate a la rescousse !

    Pour simplifier, il s'agit d'un singleton caché. On y accède comme s'il s'agissait d'une classe tout ce qu'il y a de plus normale, qu'on instancie, etc, mais toutes les instances se réfère en fait à la même chose.

    On peut d'ailleurs l'implémenter grâce à un singleton privé, si tu le souhaite vraiment :

    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
     
    class config
    {
    private:
      class config_info
      {
      private:
        config_info(const config_info&);
        config_info& operator=(const config_info&);
        config_info()
        { ... };
        ~config_info()
        { ... }
      public:
        static config_info& instance() { static config_info infos; return infos; }
      public:
         void do_somehing();
      }; 
     
      config() { }
      ~config() { }
     
      void do_something()
      {
        config_info::instance().do_something();
      }
    };
    Ce code n'a pas les faiblesses du pattern singleton (et en particulier : on peut changer l'implémentation de la classe plus tard, si nécessaire - par exemple si, finalement, le fichier config est utilisé par plusieurs applications en même temps. Alors la classe ne sera plus un monostate mais une classe normale, sans qu'on ait besoin de changer son interface).
    [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.

  5. #5
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Juste histoire de vérifier…
    La classe config n'a pas accès aux membres privés ou protégés de la classe config::config_info, si ?

  6. #6
    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 Steph_ng8 Voir le message
    Juste histoire de vérifier…
    La classe config n'a pas accès aux membres privé ou protégés de la classe config::config_info, si ?
    La partie privée d'une classe est privée à tout le monde
    [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.

  7. #7
    Nouveau membre du Club
    Profil pro
    CIO
    Inscrit en
    Novembre 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : CIO

    Informations forums :
    Inscription : Novembre 2010
    Messages : 6
    Par défaut
    Déjà je vous remercie pour vos réponses. Je suis désolé si je suis un peu confus, mais je suis un noob en C++ et tout n'est pas encore très clair...

    Donc, si je comprend bien, je vais créer ma class config avec le constructeur en privé (et pourquoi pas le destructeur) et un accesseur public...

    Ensuite, j'ai plus qu'à acceder à mes méthodes pour charger les variables puis lire directement les variables publiques...

    (Est ce que j'ai bon jusque là ???)

    Ca donnerait quelque chose du style :

    cfg.h
    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 cfg
    {
    public:
    static	cfg*	getCfg(void);
    	bool	loadRessourcesFromFile(string _str); // attribue une valeur depuis le fichier de conf à la variable _res;
    	string	_res;
     
    private:
    		cfg(){};
    		~cfg(){};
     
    static      cfg*	_singleton;
    };
    main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    main()
    {
     	_cfg = cfg::getCfg();
    	_cfg->loadRessourcesFromFile("config.cfg");
    }
    Et donc si j'instancie ma classe cfg une nouvelle fois ailleurs, les instances se referont à la même chose ?
    toto.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #include "cfg.h"
     
    class	toto
    {
    public:
    	toto(void);
    	~toto(void){};
    };
    toto.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    toto(void)
    {
    	static cfg* _cfg = cfg::getCfg();
    	//Et maintenant j'accède à la valeur _res via _cfg->_res.c_str();
    	//Exemple : 
    	MessageBoxA(NULL, _cfg->_res.c_str(), "title", NULL);
     
     
    }
    Ca semble fonctionner, par contre, est ce une méthode propre et compréhensible ? Est ce que je vais dans mur avec cette facon de faire ?

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Tu n'as pas besoin de mémoriser le pointeur de _cfg en global dans ta classe Toto, tu peux le récupérer à chaque fois: C'est la classe Cfg qui s'occupe de mémoriser, et aucune autre.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    La partie privée d'une classe est privée à tout le monde
    En fait j'avais mal lu ton code…

    Mais ça me fait penser, la variable statique infos de la fonction config::config_info::instance() ne sera détruite qu'à la fin du programme.
    Cette destruction est censée avoir lieu sous quel scope ?
    Ça devrait être celui de la fonction précitée, mais elle sera déjà terminée…

  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
    Citation Envoyé par Steph_ng8 Voir le message
    En fait j'avais mal lu ton code…

    Mais ça me fait penser, la variable statique infos de la fonction config::config_info::instance() ne sera détruite qu'à la fin du programme.
    Cette destruction est censée avoir lieu sous quel scope ?
    Ça devrait être celui de la fonction précitée, mais elle sera déjà terminée…
    La destruction des variables automatiques statique se fait dans l'ordre inverse de la sortie de leurs constructeurs.

    C'est tordu, mais c'est comme ça
    [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.

  11. #11
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Ce que je voulais savoir, c'est d'où est censé être appelé son destructeur.
    Depuis la fonction qui l'a créée (mais qui pourtant est terminée), ou alors depuis un scope global ?

  12. #12
    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 Steph_ng8 Voir le message
    Ce que je voulais savoir, c'est d'où est censé être appelé son destructeur.
    Depuis la fonction qui l'a créée (mais qui pourtant est terminée), ou alors depuis un scope global ?
    Scope global : la variable statique est une variable globale non détruite, elle est donc récupérée une fois qu'on sort de la fonction main().
    [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.

  13. #13
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Donc si son destructeur est privé ou protégé, ça devrait poser problème, non ?

  14. #14
    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 Steph_ng8 Voir le message
    Donc si son destructeur est privé ou protégé, ça devrait poser problème, non ?
    Pas dans ce cas. Le destructeur n'est pas appelé explicitement dans le code, il est exécuté par le runtime.
    [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.

  15. #15
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Est-on sûr qu'il est appelé, tout court? Je ne me souviens plus du standard sur les destructions d'objets dynamiques en fin de processus...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    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 Médinoc Voir le message
    Est-on sûr qu'il est appelé, tout court? Je ne me souviens plus du standard sur les destructions d'objets dynamiques en fin de processus...
    Dans mon code, ce n'est pas une création dynamique - c'est bien une variable statique - grouvernée par (références du dernier draft avant la publication de la norme en 98) 3.7.1 et 3.6.3§1, que je cite ici :

    Citation Envoyé par Dernier Draft C++98, 3.6.3§1
    Destructors for initialized objects of static storage duration (...) are called as a result of returning from main and as a result of calling exit. These objects are destroyed in the reverse order of the completion of their constructor or of the completion of their dynamic initialization.
    L'initialisation dynamique (qui s'oppose à l'intialisation statique, mais qui n'a rien à voir avec la durée de vie dynamique) existe dès lors qu'un constructeur non trivial est exécuté pour créer un objet dont la durée de vie est statique.

    Maintenant, si tu parles du code de base-un, la seule instance de cfg créée a une durée de vie dynamique. Une telle instance ne peut être détruite que par un appel explicite à son destructeur (via delete, ou directement - auquel cas la mémoire n'est pas libérée).
    [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.

  17. #17
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Ok.
    Merci Emmanuel.

Discussions similaires

  1. problème lecture variable static d'un singleton
    Par totoscill dans le forum Langage
    Réponses: 8
    Dernier message: 28/07/2009, 08h21
  2. Variable static locale globale include
    Par moueza dans le forum Débuter
    Réponses: 2
    Dernier message: 11/06/2008, 23h21
  3. Réponses: 6
    Dernier message: 12/09/2007, 17h31
  4. Accéder aux variables static du Global.asax
    Par tscoops dans le forum ASP.NET
    Réponses: 3
    Dernier message: 10/04/2007, 14h41

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