2010-08-11 8 views
1

Si je suit dans un fichier d'en-tête:Déclaration et initialisation d'un int statique dans un en-tête

.h

Foo 
{ 
public: 
    static const int BAR = 1234; 
    ... 
}; 

Ai-je besoin aussi de définir la variable dans le Cpp, par exemple :

foo.cpp

const int Foo::BAR; 

Nous avons un problème où l'initialisation d'une statique dans un en-tête semble fonctionner sur MS Compil ers mais avec gcc sur le Mac il semble donner des erreurs de linker.

+0

duplication possible de [membres C++ définissant des entiers statiques constants dans la définition de classe] (http://stackoverflow.com/questions/3025997/c-defining-static-const-integer-members-in-class-definition) – Troubadour

Répondre

5

Vous avez besoin de la déclaration et la définition, comme vous les avez écrit. Comme il s'agit d'un entier, vous pouvez l'initialiser dans la déclaration comme vous l'avez fait, et le compilateur doit le traiter comme une constante de compilation quand cela est possible. Mais il a toujours besoin d'une (et d'une seule) définition dans un fichier source, ou vous obtiendrez des erreurs de lien quand il ne peut pas être traité comme une constante.

Apparemment, Microsoft a décidé que le comportement standard était trop confus, et "étendu" le langage pour traiter une déclaration avec un initialiseur comme une définition; voir this issue. Le résultat est que vous obtenez des erreurs de liaison (multipliez les symboles définis) si vous définissez également le symbole correctement. Vous pouvez obtenir le comportement standard en désactivant les extensions de langue (/Za).

+0

Si j'inclus le second (.cpp) un alors mon application ne liera pas sous MSC et je reçois 'un ou plusieurs symboles définis multiples'. Si je n'initialise pas le statique dans l'en-tête, alors il est lié. – Rob

+0

@Rob: MSC est faux; mettre à jour ma réponse. –

0

Les déclarations doivent être faites dans les en-têtes et initialisations doivent être effectués sur le Cpp

Il y a un article intéressant sur les variables membres statiques here.

1

Le premier fragment fonctionne pour certains environnements mais la définition est vraiment requise par certains compilateurs et bien sûr si vous prenez l'adresse de votre constante.

Si vous ne voulez pas avoir à toucher la tête et le corps pour introduire la constante, il y a encore l'ancien ENUM-trick:

class A 
{ 
    public: 
     enum { someconstant=1234 }; 
}; 

fait someconstant disponible en tant que temps de compilation constante sans la nécessité de une définition dans le corps.

+3

Le premier fragment peut fonctionner seul, s'il est toujours traité comme une constante de compilation. Mais c'est une déclaration, pas une définition, et laisser de côté la définition est une erreur. Vous obtiendrez des erreurs de lien si jamais vous essayez de prendre une référence ou un pointeur dessus, ou si pour une raison quelconque le compilateur n'a pas envie de le traiter comme une constante de compilation. –

+0

Merci d'avoir signalé cela Mike. Je suis corrigé en ce qui concerne la définition statique const int. –

0

Le fichier d'en-tête

Foo 
{ 
public: 
    static const int BAR; 
    ... 
}; 

Le fichier de code

const int Foo::BAR = 1234; 
+0

Les membres statiques constants entiers peuvent être initialisés là où ils sont déclarés dans la définition de classe. C'est une bonne idée de le faire, afin qu'ils puissent être traités comme des constantes de compilation lorsque c'est possible. –

Questions connexes