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 :

Initialisation variable membre static const double


Sujet :

C++

  1. #1
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut Initialisation variable membre static const double
    Bonjour,

    J'ai un problème d'initialisation d'une variable membre de type static const double, mais uniquemment sous Windows (Visual Studio) et pas sous Linux/MacOSX.

    Si on a la classe suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Foo
    {
      private:
        static const double forceMin = 100.0;
        static const double forceMax = 5000.0;
    };
    Sou Linux et MacOSX, aucun problème, alors que sous windows, ça ne compile pas et renvoie une erreur du style (j'ai plus le message exact):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    can't initialize non-integral static const membre
    Sous Linux et MacOSX je choisis mes options de compilation, sous windows/VisualStudio parcontre c'est très obscure pour moi.

    J'ai pas compris le problème et pourquoi il apparait uniquement sous windows.

    Merci de votre aide.

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Il me semble qu'il faut initialiser les static dans le .cpp :
    Code foo.h : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Foo
    {
      private:
        static const double forceMin;
        static const double forceMax;
    };

    Code foo.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double Foo::forceMin = 100.0;
    double Foo::forceMax = 5000.0;

    EDIT : Après une simple recherche :
    Citation Envoyé par http://stackoverflow.com/questions/9656941/why-i-cant-initialize-non-const-static-member-or-static-array-in-class
    The C++ standard allows only static constant integral or enumeration types to be initialized inside the class.

  3. #3
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    OK, c'est ce que j'ai cru comprendre aussi, mais pourquoi sous Linux et MacOSX je n'ai pas eu de problème alors que j'initialise dans le .h.

  4. #4
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 364
    Points : 5 378
    Points
    5 378
    Par défaut
    En effet, j'ai l'erreur avec VS 2008.

    Pourtant en regardant la MSDN sur le code d'erreur C2864 Microsoft dit que ça devrait marcher. Ah non :

    Bon si tu remplaces double par int, ça marche. Il doit y avoir une restriction sur le type. Reste a savoir ce qu'est une donnée "intégrale".

  5. #5
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Citation Envoyé par fregolo52 Voir le message
    Bon si tu remplaces double par int, ça marche.
    Ah nan, ça ça va pas être possible.
    Citation Envoyé par fregolo52 Voir le message
    Il doit y avoir une restriction sur le type.
    Dans les options de compilation de visual studio? D'ailleurs j'aimerai bien les connaitres.

    Citation Envoyé par fregolo52 Voir le message
    Reste a savoir ce qu'est une donnée "intégrale".
    C'est ce que je me demande également.

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par fregolo52 Voir le message
    En effet, j'ai l'erreur avec VS 2008.

    Pourtant en regardant la MSDN sur le code d'erreur C2864 Microsoft dit que ça devrait marcher. Ah non :
    Il faudrait essayer avec mingw, il me semble que Microsoft avec Visual Studio ne voulait pas suivre entièrement le C++11 (?)

    Citation Envoyé par fregolo52 Voir le message
    Bon si tu remplaces double par int, ça marche. Il doit y avoir une restriction sur le type. Reste a savoir ce qu'est une donnée "intégrale".
    Une donnée "intégrale", ce n'est pas un entier (int abréviation de integer = intégrale) ?

  7. #7
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Il faudrait essayer avec mingw, il me semble que Microsoft avec Visual Studio ne voulait pas suivre entièrement le C++11 (?)
    J'avais pensé installer et tester avec Cygwin, parcontre je savais pas que visual studio ne suivait pas entierement C++11, merci pour l'info.
    Citation Envoyé par Neckara Voir le message
    Une donnée "intégrale", ce n'est pas un entier (int abréviation de integer = intégrale) ?
    C'est ce que je me disait, mais pourquoi pas mettre integer dans ce cas?
    A moins qu'il y ait juste une différence subtile.

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par LinuxUser Voir le message
    J'avais pensé installer et tester avec Cygwin, parcontre je savais pas que visual studio ne suivait pas entierement C++11, merci pour l'info.
    Il m'a semblé l'avoir lu mais je n'en suis pas sûr à 100%.

    Citation Envoyé par LinuxUser Voir le message
    C'est ce que je me disait, mais pourquoi pas mettre integer dans ce cas?
    A moins qu'il y ait juste une différence subtile.
    Integer fait référence à int et integral à tous les entiers de (unsigned) char à (unsigned)long long int ?

  9. #9
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par fregolo52
    Reste a savoir ce qu'est une donnée "intégrale".
    Citation Envoyé par LinuxUser
    C'est ce que je me demande également.
    Pour visualiser ce que recouvre l'ensemble des types "integral" :
    http://home.roadrunner.com/~hinnant/TypeHiearchy.pdf

    Edit : En C++03 seul les types const static "integral" et enum peuvent être initialisés dans la classe (dans le .h). Donc si ça marche pour les doubles avec GCC c'est probablement du à une extension, il faudrait essayer avec l'option -pedantic et voir si ça génère un warning.

  10. #10
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Pour visualiser ce que recouvre l'ensemble des types "integral" :
    http://home.roadrunner.com/~hinnant/TypeHiearchy.pdf

    Edit : En C++03 seul les types const static "integral" et enum peuvent être initialisés dans la classe (dans le .h). Donc si ça marche pour les doubles avec GCC c'est probablement du à une extension, il faudrait essayer avec l'option -pedantic et voir si ça génère un warning.
    En effet tu as tout à fait raison, il me semblait avoir mis l'option -pedantic et en fait nan, je l'avais oublié.
    A présent cela génère l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    erreur: floating-point literal cannot appear in a constant-expression
    attention : ISO C++ forbids initialization of member constant ‘Foo::forceMax’ of non-integral type ‘const double[-pedantic]

  11. #11
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Je dois donc initailiser mes membres dans le cpp plutôt alors.

  12. #12
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Je dois donc initailiser mes membres static const double dans le constructeur dans le cpp alors.

    Moi je trouvais cela mieux de les initialiser directement dans le .h plutot que dans le constructeur.

  13. #13
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par LinuxUser Voir le message
    Je dois donc initailiser mes membres static const double dans le constructeur dans le cpp alors.

    Moi je trouvais cela mieux de les initialiser directement dans le .h plutot que dans le constructeur.
    On initialise pas les variables statique (et surtout const) dans un constructeurs.

    Cf mon premier post.

  14. #14
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Code foo.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double Foo::forceMin = 100.0;
    double Foo::forceMax = 5000.0;
    Oui c'est vrai, je n'avais pas vu.
    Mais de le .cpp, tu fais cette initialisation où? Tout au début, en dehors de tout alors (comme une varible globale)?

  15. #15
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    C'est comme lorsque tu implémentes une méthode de ta classe.

    Code .cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Foo::Foo(void)
    {
    }
     
    bool Foo::fooo(void)
    {
          return m_fooo;
    }
     
    bool Foo::m_fooo = true;

  16. #16
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    D'accord, j'ai compris, je vais tester à présent.

  17. #17
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Ca ne marche pas, le compilateur considère que dans le .cpp j'essaye de définir une seconde fois une varible qui existe déjà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ...has a previous declaration as...
    EDIT: en fait il fallait "répéter" le mot clef const, et là ça marche.
    Foo.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const double Foo::forceMin = 100.0;
    et non pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    double Foo::forceMin = 100.0;
    Dans ce cas, pourquoi ça râle pas pour le mot clef static que je n'est pas "répété" ?

    Je rappelle le Foo.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Foo
    {
    private:
      static const double forceMin;
    };
    Petite question subsidiaire, comment préfixeriez-vous cette varible membre pour indiquer qu'il s'agit d'un static const?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    s_forceMin;
    s_constForceMin;
    ...

  18. #18
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Pour le const c'est de ma faute désolé

    Pour le static, il peut avoir 3 effets/signification.
    Si tu le rajoutes à l'extérieur de ta classe, tu vas dire que ta variable ne peut être visible que dans le fichier où tu l'a déclaré.

    Sinon pour la préfixé, je ne mettrait que m_machin pour dire que c'est un membre, mais pas plus.

  19. #19
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Donc
    Foo.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // visible uniquement dans Foo.cpp
    static const double Foo::forceMin = 100.0;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // je vois pas la difference 
    const double Foo::forceMin = 100.0;

  20. #20
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    La différence est assez simple :
    erreur : 'static' may not be used when defining (as opposed to declaring) a static data member [-fpermissive]
    Un membre doit être visible dans toute la classe, et non pas être visible dans un seul fichier.

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

Discussions similaires

  1. Initialisation de membre static
    Par Derfh dans le forum C++
    Réponses: 3
    Dernier message: 02/12/2014, 08h47
  2. Initialisation d'un membre static const
    Par la_urre dans le forum Langage
    Réponses: 4
    Dernier message: 07/10/2010, 10h31
  3. [POO] Définition des variables membre static
    Par AurélienB dans le forum Langage
    Réponses: 13
    Dernier message: 18/02/2008, 11h39
  4. Initialisation de membres static const
    Par NiamorH dans le forum C++
    Réponses: 16
    Dernier message: 14/01/2008, 16h50
  5. Réponses: 2
    Dernier message: 30/10/2006, 16h40

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