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 :

Initialisation d'un membre static const


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Août 2009
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 36
    Par défaut Initialisation d'un membre static const
    Bonjour à tous,

    Je suis confronté à un problème lorsque j'essaie d'initialiser un champ de ma classe déclaré static const:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class A{
       public:
           static const int MAX = 0;
    };
    J'ai vu sur certains exemples que ceci était possible (déclaration + définition dans le .h pour les static const de types intégraux).
    En compilant sous GCC, cela fonctionne aussi, mais c'est en faisant le link que j'obtiens l'erreur : "référence indéfinie vers com::bla::A::MAX".

    J'en ai donc déduit qu'il faut définir le membre dans le .cpp, de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // A.h
    class A{
       public:
           static const int MAX;
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // A.cpp
    const int A::MAX = 0;
    Nouveau problème, ce code est soumis au problème du fiasco dans l'ordre d'initialisation des membres statiques. Il faut donc que je transforme ce code en utilisant la solution usuelle (passer par une fonction appelée à chaque fois).

    Nouveau problème : si je passe par cette solution, je ne peux plus profiter du static const. Je m'explique : je veux que mon membre MAX puisse être utilisé dans le case d'un switch. Or, si je passe par la fonction, je ne pourrais pas utiliser MAX dans un case, car on ne peut pas y appeler de méthode.

    Avez-vous déjà rencontré ce problème ? Est-ce bien GCC qui n'accepte pas la définition dans le .h ?

    Désolé, j'ai été un peu long, mais j'espère clair. Merci d'avance pour votre aide !

  2. #2
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par la_urre Voir le message
    Bonjour à tous,

    Je suis confronté à un problème lorsque j'essaie d'initialiser un champ de ma classe déclaré static const:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class A{
       public:
           static const int MAX = 0;
    };
    J'ai vu sur certains exemples que ceci était possible (déclaration +
    définition dans le .h pour les static const de types intégraux).
    Exact. Il y a quelques tres vieux compilateurs sur lesquels ce n'etait pas
    possible (et on passait par des enum).

    En compilant sous GCC, cela fonctionne aussi, mais c'est en faisant
    le link que j'obtiens l'erreur : "référence indéfinie vers
    com::bla::A::MAX".
    Exemple complet reproduisant le probleme. Je ne l'ai pas avec ma
    collection de gcc (en gros, tout depuis 2.95)

    J'en ai donc déduit qu'il faut définir le membre dans le .cpp, de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // A.h
    class A{
       public:
           static const int MAX;
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // A.cpp
    const int A::MAX = 0;
    C'est aussi possible.

    Nouveau problème, ce code est soumis au problème du fiasco dans
    l'ordre d'initialisation des membres statiques. Il faut donc que je
    transforme ce code en utilisant la solution usuelle (passer par une
    fonction appelée à chaque fois).
    Pourquoi? C'est initialise par une constante, donc avant toute
    initialisation dynamique.

    Nouveau problème : si je passe par cette solution, je ne peux plus
    profiter du static const. Je m'explique : je veux que mon membre MAX puisse
    être utilisé dans le case d'un switch. Or, si je passe par la fonction, je
    ne pourrais pas utiliser MAX dans un case, car on ne peut pas y appeler de
    méthode.
    Meme sans le probleme de l'intialisation dynamique, ce n'est pas possible
    (la valeur n'est plus visible a la generation de code).

  3. #3
    Membre averti
    Inscrit en
    Août 2009
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 36
    Par défaut
    En fait j'utilise MinGW32-g++, je me suis trompé. Peut-être celui-ci ne supporte pas cette syntaxe... ?

    Je n'ai pas compris votre dernière phrase :

    Meme sans le probleme de l'intialisation dynamique, ce n'est pas possible
    (la valeur n'est plus visible a la generation de code).
    Sinon pour ce qui est de la reproduction, rien de plus simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // A.h
    class A{
        public:
            static const int MAX = 0;
    };
     
    // Exemple.cpp
    #include "A.h"
    Exemple::Exemple(){
        int a = A::MAX;
    }

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    J'ai du mal a imaginer un bug pour ca. Je vois plus facilement un effet des autres includes, c'est pour ca que je demandais un code complet compilable reproduisant le probleme.

    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
    28
    29
    30
    31
    32
    $ cat la_urre.cpp 
    class A {
        public:
            static const int MAX = 0;
    };
     
    void f() {
       int a = A::MAX;
    }
    $ foreach gcc ( g++-2.95 g++-3.2  g++-3.3  g++-3.4  g++-4.0  g++-4.1  g++-4.2  g++-4.3  g++-4.4  g++-4.5 )
    foreach? $gcc -Wall -W -c la_urre.cpp
    foreach? end
    la_urre.cpp: In function `void f()':
    la_urre.cpp:7: warning: unused variable `int a'
    la_urre.cpp: In function `void f()':
    la_urre.cpp:7: warning: unused variable `int a'
    la_urre.cpp: In function `void f()':
    la_urre.cpp:7: warning: unused variable `int a'
    la_urre.cpp: In function `void f()':
    la_urre.cpp:7: warning: unused variable 'a'
    la_urre.cpp: In function 'void f()':
    la_urre.cpp:7: warning: unused variable 'a'
    la_urre.cpp: In function 'void f()':
    la_urre.cpp:7: warning: unused variable 'a'
    la_urre.cpp: In function 'void f()':
    la_urre.cpp:7: warning: unused variable 'a'
    la_urre.cpp: In function 'void f()':
    la_urre.cpp:7: warning: unused variable 'a'
    la_urre.cpp: In function 'void f()':
    la_urre.cpp:7: warning: unused variable 'a'
    la_urre.cpp: In function 'void f()':
    la_urre.cpp:7:8: warning: unused variable 'a'

  5. #5
    Membre averti
    Inscrit en
    Août 2009
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 36
    Par défaut
    Je crois que j'ai trouvé le souci : je donnais ma constante en paramètre à une méthode, paramètre qui prenait une référence. Et apparement dans le cas des constantes déclaréés et définies directement dans le .h comme ci-dessus, le compilateur ne peut pas récupérer l'adresse de la constante, et ne peut donc pas la passer par référence. Un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class A{
        public:
            static const int MAX = 0;
    };
     
    int min(int &a, int &b){
        return a+b;
    }
     
    int main()
    {
        min(A::MAX, 0);
    }
    Ceci provoque la référence indéfinie vers A::MAX. Il faut rajouter la ligne suivante, dans A.cpp par exemple :

    J'espère que ça pourra en aider certains. Merci quand même pour votre aide.

    Voici la discussion à patir de laquelle je me suis basé : http://stackoverflow.com/questions/2...c-class-member

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Initialisation variable membre static const double
    Par LinuxUser dans le forum C++
    Réponses: 27
    Dernier message: 04/01/2013, 10h05
  2. initialisation d'un membre static
    Par GR3lh442kR dans le forum C++
    Réponses: 6
    Dernier message: 16/11/2009, 09h25
  3. Initialisation de membres static const
    Par NiamorH dans le forum C++
    Réponses: 16
    Dernier message: 14/01/2008, 16h50
  4. Réponses: 5
    Dernier message: 09/12/2007, 00h16
  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