Membres statiques (C++)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Mot clé this


Le spécificateur de classe de stockage static est utilisable dans les déclarations de classe des données et fonctions membres. Ces dernières sont dites membres statiques et ont des caractéristiques distinctes de celles des membres non statiques. Avec des membres non statiques, il “existe” une copie distincte pour chaque instance de la classe ; avec les membres statiques, une seule copie suffit, accessible sans référence à un objet précis de la classe. Si x est un membre statique de la classe X, il peut être référencé comme X::x (même si les objets de la classe X n'ont pas encore été créés). Il est possible aussi d'accéder à x en utilisant les opérateurs standard d'accès aux membres : par exemple, y.x et yptr->x où y est un objet de la classe X et yptr un pointeur sur un objet de la classe X, bien que les expressions y et yptr ne soient pas évaluées. En particulier, une fonction membre statique peut être appelée avec ou sans la syntaxe spéciale de fonction membre :

class X {
   int member_int;
public:
   static void func(int i, X* ptr);
};
void g(void)
{
   X obj;
   func(1, &obj);      // erreur à moins qu'une func() globale
                       // soit définie quelque part
   X::func(1, &obj);   // appelle la fonction statique func() de X
                       // OK pour les fonctions statiques uniquement
   obj.func(1, &obj);  // idem (OK pour fonctions statiques et
                       // non statiques)
}

Puisqu'il est possible d'appeler une fonction membre statique sans aucun objet précis en vue, celle-ci n'a aucun pointeur this. Il en résulte qu'une fonction membre statique ne peut accéder à des membres non statiques sans spécification explicite d'un objet avec . ou ->. Par exemple, avec les déclarations de l'exemple précédent, func pourrait être définie comme suit :

void X::func(int i, X* ptr)
{
   member_int = i;       // à quel objet se réfère member_int
                         // ? Erreur
   ptr->member_int = i;  // OK: maintenant nous savons !
}

A l'exception des fonctions inline, les fonctions membres statiques de classes globales ont une liaison externe. Elles ne peuvent pas être des fonctions virtuelles. Il est impossible d'avoir une fonction membre statique et non statique ayant le même nom et les mêmes types d'arguments.

La déclaration d'un membre statique de données dans la déclaration de sa classe n'est pas une définition ; il faut fournir une définition pour allouer de la mémoire et donner une valeur d'initialisation.

Les membres statiques d'une classe déclarée locale par rapport à une certaine fonction n'ont pas de liaison et ne peuvent pas être initialisés. Ceux d'une classe globale sont initialisables, comme des objets globaux ordinaires, mais uniquement dans la portée fichier. Les membres statiques imbriqués à n'importe quel niveau suivent les règles d'accès aux membres de classe, sauf qu'il est possible de les initialiser.

class X {
   static int x;
   static const int size =  5;
   class inner {
      static float f;
      void func(void);     // déclaration imbriquée
      };
public:
   char array[size];
};
int X::x = 1;
float X::inner::f = 3.14;  // initialisation imbriquée statique
void X::inner::func(void) {     /*  définit la fonction imbriquée  */  }

La principale utilité des membres statiques est qu'ils permettent de suivre des données communes à tous les objets d'une classe, comme le nombre d'objets créés, ou la dernière ressource utilisée parmi l'ensemble de celles que partagent tous les objets. Les membres statiques servent aussi à :

  • Réduire le nombre des noms globaux visibles
  • Mettre en évidence les objets statiques qui appartiennent logiquement à une classe
  • Permettre un contrôle d'accès à leurs noms.

Voir aussi