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
    Futur 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
    Points : 8
    Points
    8
    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 éprouvé 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 : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    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 sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    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?

  4. #4
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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
    Points : 4 551
    Points
    4 551
    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).

  5. #5
    Membre éprouvé 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 : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    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
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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
    Points : 4 551
    Points
    4 551
    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

  7. #7
    Futur 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
    Points : 8
    Points
    8
    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 sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    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.

  9. #9
    Membre éprouvé 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 : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    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
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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
    Points : 4 551
    Points
    4 551
    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

  11. #11
    Membre éprouvé 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 : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    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
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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
    Points : 4 551
    Points
    4 551
    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().

  13. #13
    Membre éprouvé 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 : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

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

  14. #14
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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
    Points : 4 551
    Points
    4 551
    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.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    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...

  16. #16
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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
    Points : 4 551
    Points
    4 551
    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).

  17. #17
    Membre éprouvé 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 : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    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