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 :

validite d'une static global dans une classe


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut validite d'une static global dans une classe
    Bonjour,

    J'ai une classe CMaClasse, definit dans un .h et .cpp(classique), sauf que dans mon cpp j'ai en haut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static typeList* uneListe = NULL;
    Tout fonctionne correctement, la liste est bien initialise une seule fois dans le contructeur et bien utilise.
    Maintenant j'ai un doute au niveau de la memoire.

    J'utilise ma classe ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Par exemple dans un main:
    CMaClasse* p1 = new CMaClasse();
    CMaClasse* p2 = new CMaClasse(); // <-- uneListe != NULL
    delete p1;
    CMaClasse* p3 = new CMaClasse(); // <-- uneListe != NULL
    delete p2;
    delete p3;
    La je pense que uneListe est creer une seule fois.

    Mais la:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Par exemple dans un main:
    CMaClasse* p1 = new CMaClasse();
    CMaClasse* p2 = new CMaClasse(); // <-- uneListe != NULL
    delete p1;
    
    delete p2;
    
    CMaClasse* p3 = new CMaClasse(); // <-- ici
    delete p3;
    Lorsque je cree p3, est-ce que uneListe est cense etre plein ou vide. Dans mon cas j'ai bien uneListe != NULL, mais pourtant j'ai supprimer toutes les instances de la classe(p1 et p2).
    Est-ce que c'est normal?

    PS: il est possible que la conception soit mauvaise, mais ce code n'est pas a moi, je dois le reprendre et j'aimerai deja comprendre ce qu'il fait, avant de modifier.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Une variable statique n'appartient à aucune instance de la classe, donc sa durée de vie est supérieure.

    Je ne peux pas dire grand-chose de plus sans le code du destructeur de CMaClasse...
    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.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    Ok, en fait c'est un brin complique car ce n'est pas detruit dans le destructeur.
    Enfin pour faire simple, c'est une liste de buffer, on les alloue au fur et a mesure, et plutot que de les desallouer quand on en a plus besoin, on les laisse pour les reutiliser plus tard sans passer par la case malloc(), (tout ca fait a l'aide d'un compteur...).

    Mais bon je pense que tu a repondu a ma question:
    Une variable statique n'appartient à aucune instance de la classe, donc sa durée de vie est supérieure.
    du coup si je comprend bien ces variables sont directement creer au lancement du prog, et pas a la (1ere) creation de la classe?

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Pour ta dernière question, je ne sais pas. Je ne sais pas ce que la norme permet, ni comment c'est implémenté.

    Mais ici, comme la variable est un pointeur, elle est initialisée par Autre Chose.

    Et cet AutreChose pourrait bien être le constructeur de la classe, qui ferait un if(uneListe == NULL) uneListe = new typeList();...
    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.

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par kacedda Voir le message
    du coup si je comprend bien ces variables sont directement creer au lancement du prog, et pas a la (1ere) creation de la classe?
    Pas exactement. En fait, les variables statiques sont vraiment crées lorsqu'elle sont initialisées. Dans ton exemple, c'est la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static typeList* uneListe = NULL;
    qui créé véritablement cette variable. Elle sera donc créée lorsque l'exécution passera la première fois à cet endroit. Elle sera alors stockée dans une partie de la mémoire dédiée aux variables statiques et n'en bougera pas jusqu'à la fin de l'exécution de l'appli.

    [edit]houla oui, je n'avais pas vu que c'était un pointeur... ça me parait dangereux ça :S

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Pour moi, une variable statique pointeur est moins dangereuse qu'une variable statique avec un constructeur: On contrôle mieux son le moment de son initialisation, ce qui peut être vital en cas de dépendance à un autre objet.
    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.

  7. #7
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Ta variable est dans l'unité de compilation, le .cpp. C'est généralement des choses qu'on voit beaucoup quand on programme en C ou dans du vieux code C++. Mais j'ai tendance à voire ça comme une mauvaise habitude.

    Pourquoi ne pas l'avoir rentrée dans la définition de la classe ?

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    Oups, m'ai mal exprimé
    en fait je voulai parler de maniere generale, donc ici plutot l'instance du pointeur(les 4 octets de l'adresse je crois).
    Sinon oui la liste est bien initialisé comme dis Médinoc(enfin pas loin).

    Donc sinon... je suppose que ces variables (pointeur ou pas) sont alloués au lancement du programme.

    [Edit:NiamorH] c'est pas mon code, et pour etre honnete je sais pas encore ce qui est le mieux, j'imagine qu'il y a quand meme une raison derriere tout ca

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Même si elle était dans la classe, ça ne change rien au fait qu'elle soit statique.
    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.

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    ben si, non?
    car lorsque je supprime toutes mes instances je repars a zero
    alors qu'en global non

  11. #11
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par kacedda Voir le message
    Donc sinon... je suppose que ces variables (pointeur ou pas) sont alloués au lancement du programme.
    Non, elle sont allouées lors de leur initialisation.

  12. #12
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Citation Envoyé par kacedda Voir le message
    ben si, non?
    car lorsque je supprime toutes mes instances je repars a zero
    alors qu'en global non
    Heu il n'y a rien d'automatique non. C'est à toi de farie ça toi même.

    C'est juste que la rentrer dans la classe permet de ne pas polluer l'espace de nom global.

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Il est possible de faire ça manuellement avec un compteur qu'on incrémente dans le constructeur et qu'on décrémente dans le destructeur (un peu comme un compteur de références), mais le C++ ne le fait pas à ta place, car tu n'as pas forcément envie de faire ça...
    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.

  14. #14
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    Citation Envoyé par r0d Voir le message
    Non, elle sont allouées lors de leur initialisation.
    Me suis encore mal exprimé, en fait je voulai dire que les 4 octet de l'adresse sont attribué, le &uneListe, apres je suis d'accord ca pointe nulle part jusqu'a l'initialisation.

    Et sinon j'ai du louper un coche.
    Si j'ai ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //.h
    CMaClasse{
    static unType uneVariable;
    //.cpp
    unType CMaClasse::uneVariable = null;//ou 0...
    }
    Dans mon main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CMaClasse* p1 = new CMaClasse();
    CMaClasse* p2 = new CMaClasse();
    delete p1;
    delete p2;
    // <-- ici uneVariable n'existe plus? ou existe toujours?
    La uneVariable ne doit plus exister puisque c'est une variable membre et que j'ai supprimer toutes les instances.

    Alors que si c'etait une variable globale non membre, la uneVariable existerai(enfin si j'ai bien compris)

  15. #15
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Fais le test, tu verras :

    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 Test
    {
     
      static int i;
    };
     
    int Test::i = 20;
     
     
    int main()
    {
      Test::i = 32;
      std::cout << Test::i;
    }
    Pas besoin d'instances pour que la variable existe bien...

  16. #16
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par kacedda Voir le message
    Me suis encore mal exprimé, en fait je voulai dire que les 4 octet de l'adresse sont attribué, le &uneListe, apres je suis d'accord ca pointe nulle part jusqu'a l'initialisation.
    Non ces octets ne sont pas attribués tant que la variable n'a pas été initialisée. Pour être précis, la variable n'existe pas tant qu'elle n'est pas initialisée. Pour t'en convaincre, fais le test suivant: tu initialise ta variable statique après un bout de code qui l'utilise. L'erreur obtenue n'est pas une seg fault, mais bel et bien une erreur de link à la compilation.

    En fait, les variables statiques ne sont finalement que des variables globales à l'application. Et ce que j'appelle ici 'initialisation' (je ne trouve pas mieux) n'est en fait que la déclaration.

  17. #17
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut
    Ok pour NiamorH, et j'ai fait le test de r0d, effectivement ca compile pas.
    Donc apparament me suis un peu plante, bon, au moins j'y voit un peu plus clair et je comprend mieux le code...
    Ok merci à tous pour les explications!

    ...mais?
    Mais donc si je comprend bien il n'y a aucune différence entre la déclarer en global ou en membre? Mis a part le fait qu'une variable membre est accessible de l'exterieur, enfin c'est deja une grosse difference.

  18. #18
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Oui, la différence n'est finalement qu'une histoire de portée et d'accessibilité (public, private ...).

    Mais c'est déjà une grosse différence

  19. #19
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 646
    Par défaut


    vais plus faire que des membres static pour gagner en memoire

    Thanks all

  20. #20
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Il n'y a aucune différence au niveau "runtime" (à l'execution quoi). La mémoire de la variable est allouée dès que l'executatable (ou la librairie) est chargée, initialisée avant le "main", désinitialisée après le "main". L'ordre de désinitialisation est toujours l'ordre inverse de l'initialisation, mais rien ne permet de contrôler cet ordre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    static const std::string toto = "toto";
    static const std::string tata = "tata"; // peut très bien être initialisé avant toto (mais dans ce cas sera désinitialisé après).
    Il y a quand même des différences "sémantiques" notoires...

    statique dans le source: variable uniquement liée à l'unité de compilation, invisible hors de celle-ci.

    statique privée dans la déclaration de classe: variable liée à la classe, donc visible par celle-ci mais aussi par toutes les classes amies.

    statique protégée dans la déclaration de classe: variable liée à la classe et visible par celle-ci, ses amies et les classes qui en héritent

    statique publique dans la déclaration de classe: variable globale accessible par tout le monde.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 6
    Dernier message: 13/11/2009, 16h06
  2. Réponses: 15
    Dernier message: 27/03/2009, 13h37
  3. Problème d'affectation d'une liste globale dans une classe
    Par _mich_ dans le forum Général Python
    Réponses: 4
    Dernier message: 30/06/2008, 17h50
  4. Réponses: 3
    Dernier message: 14/12/2006, 10h09
  5. Réponses: 11
    Dernier message: 08/02/2006, 16h59

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