web-dev-qa-db-fra.com

Comment déclarer une variable globale en C++

Je sais qu'on ne devrait pas utiliser de variables globales mais j'en ai besoin. J'ai lu que toute variable déclarée en dehors d'une fonction est une variable globale. Je l'ai fait, mais dans un autre fichier * .cpp, cette variable était introuvable. Donc, ce n'était pas vraiment global. N'est-il pas vrai qu'il faut créer un fichier d'en-tête GlobalVariabels.h et l'inclure dans tout autre fichier * cpp qui l'utilise?

43
Marcus Tik

J'ai lu que toute variable déclarée en dehors d'une fonction est une variable globale. Je l'ai fait, mais dans un autre fichier * .cpp, cette variable était introuvable. Donc, ce n'était pas vraiment global.

Selon le concept de scope, votre variable est globale. Cependant, ce que vous avez lu/compris est trop simplifié.


Possibilité 1

Peut-être avez-vous oublié de déclarer la variable dans l'autre unité de traduction (TU). Voici un exemple:

a.cpp

int x = 5; // declaration and definition of my global variable

b.cpp

// I want to use `x` here, too.
// But I need b.cpp to know that it exists, first:
extern int x; // declaration (not definition)

void foo() {
   cout << x;  // OK
}

En règle générale, vous placeriez extern int x; dans un fichier d'en-tête inclus dans b.cpp , ainsi que dans tout autre TU nécessitant l'utilisation de x.


Possibilité 2

De plus, il est possible que la variable ait internal linkage, ce qui signifie qu'elle n'est pas exposée dans les unités de traduction. Ce sera le cas par défaut si la variable est marquée const ([C++11: 3.5/3]):

a.cpp

const int x = 5; // file-`static` by default, because `const`

b.cpp

extern const int x;    // says there's a `x` that we can use somewhere...

void foo() {
   cout << x;    // ... but actually there isn't. So, linker error.
}

Vous pouvez résoudre ce problème en appliquant extern à definition également:

a.cpp

extern const int x = 5;

Toute cette malarkie équivaut à peu près au désordre que vous traversez en rendant les fonctions visibles/utilisables au-delà de TU, mais avec quelques différences dans la façon de procéder.

66

Vous déclarez la variable en tant que extern dans un en-tête commun:

//globals.h
extern int x;

Et définissez-le dans un fichier d'implémentation.

//globals.cpp
int x = 1337;

Vous pouvez ensuite inclure l'en-tête partout où vous avez besoin d'y accéder.

Je vous suggère également de placer la variable dans une variable namespace.

49
Luchian Grigore

En plus des autres réponses ici, si la valeur est une constante intégrale, une énumération publique dans une classe ou une structure fonctionnera. Une variable - constante ou non - à la racine d'un espace de noms est une autre option, ou un membre public statique d'une classe ou d'une structure est une troisième option. 

MyClass::eSomeConst (enum)
MyNamespace::nSomeValue 
MyStruct::nSomeValue (static) 
4
JTeagle

Je ne suis pas sûr que cela soit vrai, mais cela semble fonctionner pour moi.

someHeader.h
inline int someVar;

Je n'ai pas de lien/plusieurs problèmes de définition et cela "fonctionne" ...; -)

C'est assez pratique pour les tests "rapides" ... Essayez d'éviter les variables globales, parce que tout le monde le dit ...; -)

0
Dariusz