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.

9voto

thecoshman Points 2927

Je pense qu'il vaut la peine d'ajouter qu'une variable statique n'est pas la même qu'une variable constante.

en utilisant une variable constante dans une classe

struct Foo{
    const int a;
    Foo(int b) : a(b){}
}

et nous le déclarerions ainsi

fooA = new Foo(5);
fooB = new Foo(10);
// fooA.a = 5;
// fooB.a = 10;

Pour une variable statique

struct Bar{
    static int a;
    Foo(int b){
        a = b;
    }
}
Bar::a = 0; // définir une valeur pour a

qui est utilisé comme ça

barA = new Bar(5);
barB = new Bar(10);
// barA.a = 10;
// barB.a = 10;
// Bar::a = 10;

Vous voyez ce qui se passe ici. La variable constante, qui est instanciée avec chaque instance de Foo, car Foo est instancié a une valeur séparée pour chaque instance de Foo, et elle ne peut pas être modifiée par Foo du tout.

Alors qu'avec Bar, il n'y a qu'une seule valeur pour Bar :: a, peu importe le nombre d'instances de Bar créées. Ils partagent tous cette valeur, et vous pouvez également y accéder sans qu'il n'y ait d'instances de Bar. La variable statique se conforme également aux règles de public/privé, donc vous pourriez faire en sorte que seules les instances de Bar puissent lire la valeur de Bar :: a;

9voto

Sergio Basurco Points 2138

Juste pour ajouter à ce qui a déjà été répondu. Pour initialiser un membre statique complexe, vous pouvez le faire comme suit :

Déclarez votre membre statique comme d'habitude.

// myClass.h
class myClass
{
static complexClass s_complex;
//...
};

Créez une petite fonction pour initialiser votre classe si ce n'est pas trivial à faire. Cela ne sera appelé qu'une seule fois lors de l'initialisation du membre statique. (Notez que le constructeur de copie de complexClass sera utilisé, il doit donc être bien défini).

//class.cpp    
#include myClass.h
complexClass initFunction()
{
    complexClass c;
    c.add(...);
    c.compute(...);
    c.sort(...);
    // Etc.
    return c;
}

complexClass myClass::s_complex = initFunction();

2voto

Mark Lakata Points 3458

Si votre objectif est d'initialiser la variable statique dans votre fichier d'en-tête (au lieu d'un fichier *.cpp, ce que vous voulez peut-être si vous suivez un idiome "header only"), alors vous pouvez contourner le problème d'initialisation en utilisant un modèle. Les variables statiques modélisées peuvent être initialisées dans un en-tête, sans causer la définition de plusieurs symboles.

Voir ici pour un exemple:

Initialisation de membre statique dans un modèle de classe

2voto

RuslanK Points 144

Facultativement, déplacez toutes vos constantes vers le fichier .cpp sans les déclarer dans le fichier .h. Utilisez un espace de noms anonyme pour les rendre invisibles au-delà du module cpp.

// MyClass.cpp

#include "MyClass.h"

// espace de noms anonyme
namespace
{
    string RE_ANY = "([^\\n]*)";
    string RE_ANY_RELUCTANT = "([^\\n]*?)";
}

// fonction membre (static ou non)
bool MyClass::foo()
{
    // logique qui utilise des constantes
    return RE_ANY_RELUCTANT.size() > 0;
}

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