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 :

Variable globale modifiée dans une fct et réinitialisée dans une autre fct


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 7
    Points : 7
    Points
    7
    Par défaut Variable globale modifiée dans une fct et réinitialisée dans une autre fct
    Bonjour,

    J'ai déclaré une variable globale "factsPhone" comme étant une liste de faits (classe Fact) dans un fichier header "initialization.h" et j'ai crée une fonction "initializeFactsPhone()" pour remplir "factsPhone" comme suit :

    "initialization.h" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        list<Fact> * factsPhone = new list<Fact> ();   //facts of phone
        void initializeFactsPhone(){
     
            Fact f1 (lp1, "justified", "collected");
            Fact f2 (lp2, "justified", "collected");
            Fact f3 (lp3, "justified", "collected");
            factsPhone->push_back(f1);
            factsPhone->push_back(f2);
            factsPhone->push_back(f3);
        }
    Dans un 2ème fichier Entity.cc, j'ai créé deux fonctions : la première sert à appeler la fonction "initializeFactsPhone()" pour initialiser la variable globale "factsPhone" et la 2ème fonction sert à gérer la liste "factsPhone comme suit :

    Entity.cc :

    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
    #include "initialization.h"
    ...
    void Entity::initialize()
    {
       if (strcmp("phone", getName()) == 0)
        {
            ....
            initializeFactsPhone();
            ....
        }
     
    void Entity::handleMessage(cMessage *msg)
    {
        ev << "factsPhone : " << factsPhone->empty() << endl;  //afficher 1 : liste remplie; 0 : liste vide
        int i=0;
        while (!selectedRules->empty())
        {....
         }
    }
    Mon programme commence par exécuter la fonction Entity::initialize(), j'ai pu afficher le contenu de la liste "factsPhone" dans la même fonction Entity::initialize().
    Cependant, lorsque mon programme exécute la fonction Entity::handleMessage, la liste factsPhone est vide!!! le programme affiche "1" pour "factsPhone->empty()".

    Je soupçonne que c'est un problème de gestion de variable globale modifiée au sein de la fonction "Entity::initialize()" et réinitialisée dans l'autre fonction "Entity::handleMessage".

    J'ai modifié la déclaration de "factsPhone" en rajoutant une fois "static" et une fois "extern" mais ça ne marche toujours pas.

    Comment gérer une variable globale modifiée par toutes les fonctions et non réinitialisée pour chaque fonction ?

    Pourriez vous SVP m'aider?

    Je vous remercie d'avance.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Merci de mettre ton code dans la balise idoine.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 7
    Points : 7
    Points
    7
    Par défaut
    Je m'excuse mais je n'ai pas pu modifier mon message pour mettre le code dans la balise.
    Dorénavant je vais le faire, pourriez vous m'indiquer comment le faire?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Je ne vois rien dans votre code qui permet d'affirmer que la méthode "initializeFactsPhone" soit obligatoirement appelée avant la méthode "handleMessage".

    Evitez les variables globales. Utilisez le Design Pattern Singleton au pire.

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Je te suggère de transformer ta variable globale en une classe, que tu utilise une seule fois si tu veux.

    Par exemple, plutôt qu'avoir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main () {
        initialiser_truc();
        for(int i = 0; i<10; ++i) utiliser_truc(i);
        vider_truc();
    }
    il vaut mieux avoir ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int main () {
        Truc truc();
        for(int i = 0; i<10; ++i) truc.utiliser(i);
    }
    Ainsi, il n'y a plus de variable globale (je peux avoir deux Truc), et je peux me reposer sur le destructeur de Truc pour garantir le vidage correct (c'est le RAII).
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Ou alors tu met factsPhone en static.
    En déboguant je te met ma main à coupé que ton factPhone dans initializeFactsPhone n'a pas la même adresse mémoire que celui qui est dans ton Entity.cc.
    Homer J. Simpson


  7. #7
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    c'est plutot extern, pour une globale.

    static devant une variable "globale" c'est du C-ism, qu'il ne faut pas utiliser en C++, qui garanti que chaque unité de compilation (~chaque .cpp) aura une variable différente (donc une adresse différente)

    Mais une globale, c'est souvent une erreur de compilation.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  8. #8
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Citation Envoyé par leternel Voir le message
    c'est plutot extern, pour une globale.

    static devant une variable "globale" c'est du C-ism, qu'il ne faut pas utiliser en C++, qui garanti que chaque unité de compilation (~chaque .cpp) aura une variable différente (donc une adresse différente)

    Mais une globale, c'est souvent une erreur de compilation.
    Oui autant pour moi! extern et pas static
    Le problème c'est que extern montre un gros défaut de conception ici à mon goût , encapsuler ce std::list serait une bonne solution je trouve
    Homer J. Simpson


  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par Astraya Voir le message
    Oui autant pour moi! extern et pas static
    Le problème c'est que extern montre un gros défaut de conception ici à mon goût , encapsuler ce std::list serait une bonne solution je trouve
    De toutes manières, la seule idée d'avoir une variable globale susceptible d'être modifiée, quelle que soit la manière dont elle est représentée (en ce, y compris en utilisant l'anti pattern singleton), présente déjà, en soi, un défaut de conception majeur.

    Que l'on déclare des constantes comme globales, cela peut se comprendre et se justifier : ca permet d'éviter le recours au valeur magiques, permet l'utilisation de termes plus explicites et facilite la mise à jour si la valeur vient à changer (bien que ce soit très rarement le cas )

    Mais on se rend souvent compte que ce que l'on s'apprête à déclarer comme une variable globale n'a aucun sens à être rendue disponible de manière systématique n'importe où: Éventuellement, il y a du sens à la rendre disponible dans un module, et encore... : il est rare de trouver une variable qui devra réellement être rendue accessible à plus de deux ou trois classes différentes. Dés lors, la bonne question à se poser est : pourquoi rendre la variable accessible à l'ensemble des autres classes, au risque de permettre au développeur qui utilise ces autres classes d'utiliser la variable de manière erronée (perso, la réponse est : aucune raison ne peut le jusifier )
    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

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Même si je suis globalement d'accord, il y a quelques variables que j'admets de voir en global (et/ou singleton, d'un point de vue design, c'est assez proche). En gros, ce qui est lié à du log (comme std::cout), à des factories, et c'est à peu près tout.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Héhé... Tu auras remarqué que j'ai utilisé les termes "on se rend souvent compte..." et "il est rare de trouver une variable..."

    Chaque règle a ses exceptions, et nous en avons la preuve une fois de plus ici. Globalement, je vois mal comment représenter les entrées/sorties standards, qui rentrent justement dans la catégories des objets qui risquent effectivement d'être nécessaires depuis strictement n'importe ou, sans passer par une globale quelconque (comprends : quelle qu'en soit la forme ).

    Mais je crois que l'on pourrait compter sur les doigts d'une main (allez, peut être des deux mains) les cas où l'utilisation d'une variable globale s'avère strictement justifiée
    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

Discussions similaires

  1. Réponses: 10
    Dernier message: 23/12/2013, 11h23
  2. [2.x] Variable globale modifiable
    Par LEF97 dans le forum Symfony
    Réponses: 4
    Dernier message: 21/11/2013, 00h10
  3. [AC-2003] Tester si une cellule est vide dans un classeur excel et faire une boucle
    Par moilou2 dans le forum VBA Access
    Réponses: 11
    Dernier message: 19/08/2009, 09h34
  4. Réponses: 4
    Dernier message: 19/10/2006, 17h19

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