2011-04-09 2 views
0
A.h 

class A 
{ 
    private: 
    static const int b = 50; 
    int c[b]; 
}; 

A.cpp 

#include "A.h" 
const int A::b; 

C.cpp 

#include "A.h" 

Les problèmes du compilateur me dire un avertissement b est défini plusieurs fois et on est ignorée. J'ai besoin de le définir dans la classe puisque j'ai besoin d'initialiser le tableau. Sinon, je devrais utiliser l'approche enum pour le faire. Mais je voulais savoir si c'était possible?définition const statique intégrale dans une classe dont le fichier .h est inclus dans plusieurs fichiers cpp

+0

Quel compilateur utilisez-vous? J'ai essayé ceci avec g ++ sur Ubuntu (ajouté un stub 'main()' de sorte que l'éditeur de liens s'exécute) et n'a reçu aucun avertissement du tout. – QuantumMechanic

Répondre

6

Je vais deviner que vous utilisez Visual C++, qui a une extension de langage plutôt horrible, comme décrit dans "Microsoft Extensions to C and C++":

Sur Définition Classe de const statique membres à part entière (ou ENUM)

Sous la norme (/Za), vous devez définir une définition hors classe pour les membres de données. Par exemple,

class CMyClass { 
    static const int max = 5; 
    int m_array[max]; 
} 
... 
const int CMyClass::max; // out of class definition 

Sous /Ze, la définition hors classe est facultative pour les statiques, const intégrale et const membres de données ENUM. Seules les intégrales et les énumérations statiques et const peuvent avoir des initialiseurs dans une classe; l'expression d'initialisation doit être une expression const.

Pour éviter les erreurs lorsqu'une définition hors classe est fournie (lorsque la définition hors classe est fournie dans un fichier d'en-tête et que le fichier d'en-tête est inclus dans plusieurs fichiers source), vous devez utiliser selectany. Par exemple:

__declspec(selectany) const int CMyClass::max = 5; 

Le drapeau /Ze est activé par défaut. Vous devez utiliser explicitement le drapeau /Za si vous ne voulez pas les extensions de langue.

Le code tel qu'il est écrit compile et lie tel quel sans erreur en utilisant g ++ 4.5.2, Clang 3.0 et Visual C++ 2010 avec l'ensemble d'indicateurs /Za. Suppression de la définition du fichier .cpp résout le problème si vous souhaitez compiler avec Visual C++, mais cela ne fonctionnera pas avec les autres compilateurs (ou avec /Za) si vous essayez d'utiliser le membre de données. Pour une solution portable, vous pouvez utiliser un bloc de compilation conditionnelle qui vérifie si les extensions sont activées:

#ifndef _MSC_EXTENSIONS 
const int A::b; 
#endif 
+1

"mais alors votre code ne fonctionnera pas avec d'autres compilateurs" Ceci est incorrect. Le code compilera et fonctionnera très bien avec gcc, (juste vérifié). Peut-être pourriez-vous fournir un exemple de compilateur où cette ligne est vraiment nécessaire? –

+0

@Matt: Dans ce cas spécifique, la définition est inutile car le membre de données statiques n'est pas _used_ (dans le sens de la règle de définition unique du terme). Si le membre de données statiques était _used_ (par exemple, si '& A :: b' apparaissait quelque part dans le programme), vous obtiendriez assurément une erreur de l'éditeur de liens. Si vous n'avez pas l'intention d'utiliser le membre de données, l'approche préférée consiste à empêcher l'utilisation en utilisant une énumération, par ex. 'enum {b = 50};'. –

+0

@Matt: Vous avez raison, cependant, il était tout à fait clair que j'ai dit "votre code ne fonctionnera pas." Je ne voulais pas dire "le code spécifique que vous avez posté ici ne fonctionnera pas", je voulais dire "en général, le code que vous écrivez ne fonctionnera pas." J'ai clarifié cette phrase. Merci d'avoir fait remarquer cela. –

0

Vous avez donné des définitions contradictoires. En donnant à la variable une valeur dans la définition de la classe, vous dites que c'est une constante de compilation qui n'a pas besoin de stockage. Ensuite, vous essayez de le stocker dans le fichier .cpp. Retirez-le du .cpp et tout ira bien. N'essayez pas d'en prendre l'adresse.

+0

Et n'essayez pas de lier une référence, ou [utilisez-le dans certaines formes d'expressions conditionnelles] (http://stackoverflow.com/questions/5446005). Y at-il un avantage à utiliser un membre de données statique de type intégrale non défini lorsque vous pouvez simplement utiliser une énumération? –

Questions connexes