584 votes

Initialisation de membres statiques privés

Cela se sent comme une question stupide, mais quelle est la meilleure façon d’initialiser un membre de données privé, statique en C++ ? J’ai essayé ceci mais il me donne des erreurs de l’éditeur de liens étranges :

Je devine que c’est parce que je ne peux pas initialiser un membre privé d’en dehors de la classe. Donc, ce qui est le meilleur moyen de faire cela ?

617voto

Loki Astari Points 116129

La déclaration de la classe doit être dans le fichier d'en-tête (Ou dans le fichier source si non partagé).
Fichier: foo.h

class foo
{
    private:
        static int i;
};

Mais l'initialisation doit être dans le fichier source.
Fichier: foo.cpp

int foo::i = 0;

Si l'initialisation est dans le fichier d'en-tête, puis chaque fichier qui contient le fichier d'en-tête aura une définition du membre statique. Ainsi, au cours de la phase d'édition de liens, vous obtiendrez de l'éditeur de liens erreurs que le code d'initialisation de la variable sera défini dans plusieurs fichiers source.

Remarque: Matt Curtis: les points que C++ permet la simplification de la ci-dessus si la variable membre statique est de const int type (par exemple, int, bool, char), ou de tout type, si vous êtes à l'aide de C++11. Vous pouvez déclarer et initialiser la variable de membre directement à l'intérieur de la déclaration de la classe dans le fichier d'en-tête:

class foo
{
    private:
        static int const i = 42;
};

104voto

Matt Curtis Points 12454

Pour une variable:

toto.h :

foo.cpp :

C’est parce qu’il ne peut exister qu’une seule instance de dans votre programme. C’est le genre de l’équivalent de dans un fichier d’en-tête et `` dans un fichier source.

Pour une constante , vous pouvez mettre la valeur directement dans la déclaration de classe :

33voto

Joshua Clayton Points 536

Pour les futurs spectateurs de cette question, je tiens à souligner que vous devriez éviter ce monkey0506 suggère.

Fichiers d'en-tête sont pour les déclarations.

Fichiers d'en-tête compilé une seule fois pour chaque fichier cpp qui, directement ou indirectement #inclut, et le code en dehors de toute fonction est exécutée lors de l'initialisation du programme, avant le main().

En mettant: "foo::i = VALEUR;" dans l'en-tête, foo:je vais être affectée la valeur de la VALEUR (quelle qu'elle soit) pour chaque fichier cpp, et ces affectations se produire dans une période indéterminée, afin (déterminé par l'éditeur de liens) avant le main() est exécutée.

Si nous #définir la VALEUR d'un nombre différent dans l'un de nos fichiers cpp? Compiler fine et nous n'avons aucun moyen de savoir qui gagne un jusqu'à ce que nous exécuter le programme.

Ne jamais mettre le code exécuté dans un en-tête pour la même raison que vous n'avez jamais #include d'un .fichier cpp.

inclure les gardes (qui je suis d'accord que vous devriez toujours utiliser) de vous protéger de quelque chose de différent: le même en-tête étant indirectement #inclus plusieurs fois lors de la compilation d'un seul .fichier cpp

23voto

Johann Gerell Points 10649

Avec un compilateur de Microsoft, les variables statiques qui ne sont pas -comme peut également être défini dans un fichier d’en-tête, mais en dehors de la déclaration de classe, avec les spécifiques de Microsoft .

Notez que je ne dis pas que ce qui est bon, que je viens de dire que c’est possible.

9voto

monkey_05_06 Points 411

Je n'ai pas assez de rep ici pour ajouter un commentaire, mais IMO il est de bon ton d'écrire vos en-têtes avec #include gardes de toute façon, comme l'a noté Paranaix il y a quelques heures permettrait d'éviter un multiple de définition de l'erreur. Sauf si vous êtes déjà à l'aide d'un fichier CPP séparé, il n'est pas nécessaire d'utiliser un juste pour initialiser statique non-membres à part entière.

#ifndef FOO_H
#define FOO_H
#include "bar.h"

class foo
{
private:
    static bar i;
};

bar foo::i = VALUE;
#endif

Je ne vois pas de nécessité d'utiliser un fichier CPP pour cela. Bien sûr, vous pouvez, mais il n'y a pas de raison technique pour laquelle vous devriez avoir.

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