web-dev-qa-db-fra.com

Variables statiques en C ++

J'aimerais savoir quelle est la différence entre les variables statiques d'un fichier d'en-tête et celles déclarées dans une classe. Lorsque la variable statique est déclarée dans un fichier d’en-tête, sa portée est limitée au fichier .h ou à toutes les unités. De plus, la variable statique est généralement initialisée dans un fichier .cpp lorsqu'elle est déclarée dans une classe, n'est-ce pas? Cela signifie-t-il que la portée de la variable statique est limitée à 2 unités de compilation?

61
brett

Excusez-moi, quand je réponds à vos questions en désordre, cela facilite la compréhension de cette façon.

Lorsque la variable statique est déclarée dans un fichier d’en-tête, sa portée est limitée au fichier .h ou à toutes les unités.

Il n’existe pas de "champ de fichier en-tête". Le fichier d'en-tête est inclus dans les fichiers source. L'unité de traduction est le fichier source , y compris le texte des fichiers d'en-tête. Tout ce que vous écrivez dans un fichier d'en-tête est copié dans chaque fichier source inclus.

En tant que telle, une variable statique déclarée dans un fichier d'en-tête est semblable à une variable statique dans chaque fichier source individuel.

Depuis la déclaration d'une variable static de cette façon signifie un lien interne, chaque unité de traduction #includeing votre fichier d'en-tête obtient sa variable own, individual (qui n'est pas visible en dehors de votre unité de traduction). Ce n'est généralement pas ce que vous voulez.

J'aimerais savoir quelle est la différence entre les variables statiques d'un fichier d'en-tête et celles déclarées dans une classe.

Dans une déclaration de classe, static signifie que toutes les instances de la classe partagent cette variable membre; c'est-à-dire que vous pourriez avoir des centaines d'objets de ce type, mais chaque fois qu'un de ces objets fait référence à la variable static (ou "classe"), c'est la même valeur pour tous les objets. Vous pourriez penser à cela comme une "classe globale".

De plus, la variable statique est généralement initialisée dans un fichier .cpp lorsqu'elle est déclarée dans une classe, n'est-ce pas?

Oui, une (et seule une ) unité de traduction doit initialiser la classe variable.

Cela signifie-t-il que la portée de la variable statique est limitée à 2 unités de compilation?

Comme j'ai dit:

  • Un en-tête n'est pas une unité de compilation,
  • static signifie des choses complètement différentes selon le contexte.

Global static limite la portée à l'unité de traduction. La classe static signifie globale pour toutes les instances.

J'espère que ça aide.

PS: Vérifiez le dernier paragraphe de la réponse de Chubsdad, expliquant comment vous ne devriez pas utiliser static en C++ pour indiquer le lien interne, mais les espaces de noms anonymes. (Parce qu'il a raison. ;-))

86
DevSolar

Variable statique dans un fichier d'en-tête:

dire 'common.h' a

static int zzz;

Cette variable 'zzz' a un lien interne (cette même variable n’est pas accessible dans les autres unités de traduction). Chaque unité de traduction qui comprend 'common.h' a son propre objet unique de nom 'zzz'.

Variable statique dans une classe:

La variable statique dans une classe ne fait pas partie du sous-objet de la classe. Il n'y a qu'une seule copie d'un membre de données statique partagée par tous les objets de la classe.

$ 9.4.2/6 - "Les membres de données statiques d'une classe dans la portée de l'espace de noms ont une liaison externe (3.5). Une classe locale ne doit pas avoir de membres de données statiques."

Alors disons 'myclass.h' a

struct myclass{
   static int zzz;        // this is only a declaration
};

et myclass.cpp a

#include "myclass.h"

int myclass::zzz = 0           // this is a definition, 
                               // should be done once and only once

et "hisclass.cpp" a

#include "myclass.h"

void f(){myclass::zzz = 2;}    // myclass::zzz is always the same in any 
                               // translation unit

et "ourclass.cpp" a

#include "myclass.h"
void g(){myclass::zzz = 2;}    // myclass::zzz is always the same in any 
                               // translation unit

Ainsi, les membres statiques de classe ne sont pas limités à 2 unités de traduction. Ils doivent être définis une seule fois dans l’une des unités de traduction.

Remarque: l'utilisation de 'static' pour déclarer la variable de portée du fichier est obsolète et l'espace de nom sans nom est un substitut supérieur.

46
Chubsdad

Une variable statique déclarée dans un fichier d'en-tête en dehors de la classe serait file-scoped dans chaque fichier .c incluant l’en-tête. Cela signifie qu'une copie distincte d'une variable du même nom est accessible dans chacun des fichiers .c où vous incluez le fichier d'en-tête.

Une variable de classe statique, d'autre part, est class-scoped et la même variable statique est disponible pour chaque unité de compilation comprenant l'en-tête contenant la classe avec la variable statique.

14
Goutham