web-dev-qa-db-fra.com

Comment initialiser un membre const statique en C ++?

Est-il possible d'initialiser une valeur de constante statique en dehors du constructeur? Peut-il être initialisé au même endroit où se trouvent les déclarations des membres?

class A {
private:
  static const int a = 4;
  /*...*/
};
61
anarhikos

OUI vous pouvez mais seulement pour les types int. Si vous voulez que votre membre statique soit de tout autre type, vous devrez le définir quelque part dans un fichier cpp.

class A{
private:
 static const int a = 4; // valid
 static const std::string t ; // can't be initialized here
 ...
 ...
};


// in a cpp file where the static variable will exist 
const std::string A::t = "this way it works";

Notez également que cette règle a été supprimée dans C++ 11, maintenant (avec un compilateur fournissant la fonctionnalité), vous pouvez initialiser ce que vous voulez directement dans la déclaration de membre de classe.

70
Klaim

membres de données statiques (C++ uniquement)

La déclaration d'un membre de données statiques dans la liste des membres d'une classe n'est pas une définition. Vous devez définir le membre statique en dehors de la déclaration de classe, dans la portée de l'espace de noms. Par exemple:

class X
{
public:
      static int i;
};
int X::i = 0; // definition outside class declaration

Une fois que vous avez défini un membre de données statiques, il existe même si aucun objet de la classe du membre de données statiques n'existe. Dans l'exemple ci-dessus, aucun objet de classe X n'existe même si le membre de données statiques X :: i a été défini.

Les membres de données statiques d'une classe dans la portée de l'espace de noms ont une liaison externe. L'initialiseur d'un membre de données statiques est dans la portée de la classe déclarant le membre.

Un membre de données statiques peut être de tout type, à l'exception de void ou void qualifié de const ou volatile. Vous ne pouvez pas déclarer un membre de données statiques comme mutable.

Vous ne pouvez avoir qu'une seule définition d'un membre statique dans un programme. Les classes sans nom, les classes contenues dans des classes sans nom et les classes locales ne peuvent pas avoir de membres de données statiques.

Les membres de données statiques et leurs initialiseurs peuvent accéder à d'autres membres statiques privés et protégés de leur classe. L'exemple suivant montre comment vous pouvez initialiser des membres statiques à l'aide d'autres membres statiques, même si ces membres sont privés:

class C {
      static int i;
      static int j;
      static int k;
      static int l;
      static int m;
      static int n;
      static int p;
      static int q;
      static int r;
      static int s;
      static int f() { return 0; }
      int a;
public:
      C() { a = 0; }
      };

C c;
int C::i = C::f();    // initialize with static member function
int C::j = C::i;      // initialize with another static data member
int C::k = c.f();     // initialize with member function from an object
int C::l = c.j;       // initialize with data member from an object
int C::s = c.a;       // initialize with nonstatic data member
int C::r = 1;         // initialize with a constant value

class Y : private C {} y;

int C::m = Y::f();
int C::n = Y::r;
int C::p = y.r;       // error
int C::q = y.f();     // error

Les initialisations de C :: p et C :: q provoquent des erreurs car y est un objet d'une classe dérivée en privé de C et ses membres ne sont pas accessibles aux membres de C.

Si un membre de données statiques est de type const intégral ou énumération const, vous pouvez spécifier un initialiseur constant dans la déclaration du membre de données statiques. Cet initialiseur constant doit être une expression constante intégrale. Notez que l'initialiseur constant n'est pas une définition. Vous devez toujours définir le membre statique dans un espace de noms englobant. L'exemple suivant le démontre:

#include <iostream>
using namespace std;

struct X {
  static const int a = 76;
};

const int X::a;

int main() {
  cout << X::a << endl;
}

Les jetons = 76 à la fin de la déclaration du membre de données statiques a est un initialiseur constant.

32
user195488

Juste pour être complet, j'ajoute à propos des variables de membre de modèle statique.

template<class T> struct X{
   static T x;
};

template<class T> T X<T>::x = T();

int main(){
   X<int> x;
}
13
Chubsdad

Vous ne pouvez pas initialiser des membres statiques dans les constructeurs. Types intégraux que vous pouvez initialiser en ligne lors de leur déclaration. D'autres membres statiques doivent être définis (dans un .cpp) fichier:

// .h
class A{
private:
 static const int a = 4;
 static const foo bar;
 ...
 ...
};

// .cpp
const foo A::bar = ...;
6
sbi