117 votes

Initialiser les variables statiques dans une classe C++ ?

J'ai remarqué que certaines de mes fonctions dans une classe n'accèdent en fait pas à l'objet, donc je les ai rendues static. Ensuite, le compilateur m'a dit que toutes les variables auxquelles elles accèdent doivent également être statiques - assez compréhensible jusqu'ici. J'ai un tas de variables de type string telles que

chaîne RE_ANY = "([^\\n]*)";
chaîne RE_ANY_RELUCTANT = "([^\\n]*?)";

et ainsi de suite dans la classe. Je les ai alors toutes rendues static const car elles ne changent jamais. Cependant, mon programme ne se compile que si je les sors de la classe: sinon, MSVC++2010 se plaint "Seules des variables intégrales constantes statiques peuvent être initialisées à l'intérieur d'une classe".

Eh bien, c'est malheureux. Y a-t-il une solution de contournement? J'aimerais les laisser à l'intérieur de la classe à laquelle elles appartiennent.

173voto

Mike Seymour Points 130519

Ils ne peuvent pas être initialisés à l'intérieur de la classe, mais ils peuvent être initialisés à l'extérieur de la classe, dans un fichier source :

// à l'intérieur de la classe
class Thing {
    static string RE_ANY;
    static string RE_ANY_RELUCTANT;
};

// dans le fichier source
string Thing::RE_ANY = "([^\\n]*)";
string Thing::RE_ANY_RELUCTANT = "([^\\n]*?)";

Mise à jour

Je viens de remarquer la première ligne de votre question - vous ne voulez pas rendre ces fonctions static, vous voulez les rendre const. Les rendre static signifie qu'elles ne sont plus associées à un objet (donc elles ne peuvent pas accéder à des membres non statiques), et rendre les données statiques signifie qu'elles seront partagées avec tous les objets de ce type. Cela ne correspond peut-être pas à ce que vous voulez. Les rendre const signifie simplement qu'elles ne peuvent pas modifier de membres, mais peuvent toujours y accéder.

44voto

X Stylish Points 1331

Certaines réponses, y compris la réponse acceptée, semblent être un peu trompeuses.

Vous n'êtes pas obligé de

  • Attribuer toujours une valeur aux objets statiques lors de l'initialisation car c'est optionnel.
  • Créer un autre fichier .cpp pour l'initialisation car cela peut se faire dans le même fichier d'en-tête.

Vous pouvez même initialiser un objet statique dans le même espace de classe comme une variable normale en utilisant le mot-clé inline.


Initialiser sans valeurs dans le même fichier

#include 
class A
{
    static std::string str;
    static int x;
};
std::string A::str;
int A::x;

Initialiser avec des valeurs dans le même fichier

#include 
class A
{
    static std::string str;
    static int x;
};
std::string A::str = "SO!";
int A::x = 900;

Initialiser dans le même espace de classe en utilisant le mot-clé inline

#include 
class A
{
    static inline std::string str = "SO!";
    static inline int x = 900;
};

39voto

Santiago V. Points 499

Mike Seymour vous a donné la bonne réponse, mais pour ajouter...
C++ vous permet de déclarer et de définir uniquement dans le corps de votre classe des types intègres const static, comme le dit le compilateur. Vous pouvez donc faire réellement :

class Foo
{
    static const int someInt = 1;
    static const short someShort = 2;
    // etc.
};

Et vous ne pouvez pas faire cela avec un autre type, dans ce cas vous devriez les définir dans votre fichier .cpp.

24voto

0ax1 Points 31

Depuis C++11, cela peut être fait à l'intérieur d'une classe avec constexpr.

class stat {
    public:
        // Initialiser à l'intérieur de la classe
        static constexpr double inlineStaticVar = 22;
};

La variable peut maintenant être accédée avec :

stat::inlineStaticVar

20voto

peoro Points 12875

Les variables membres statiques doivent être déclarées dans la classe puis définies en dehors de celle-ci!

Il n'y a pas de solution de contournement, il suffit de mettre leur définition réelle dans un fichier source.


D'après votre description, on dirait que vous n'utilisez pas les variables statiques de la bonne manière. Si elles ne changent jamais, vous devriez utiliser des variables constantes à la place, mais votre description est trop générale pour dire quelque chose de plus.

Les variables membres statiques ont toujours la même valeur pour n'importe quelle instance de votre classe: si vous changez une variable statique d'un objet, cela changera également pour tous les autres objets (et en fait vous pouvez également y accéder sans une instance de la classe - c'est-à-dire un objet).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X