57 votes

C / C ++: Fonction statique dans le fichier d'en-tête, qu'est-ce que cela signifie?

Je sais ce que cela signifie lorsqu'il est déclaré dans le fichier source. En lisant du code, je constate que la fonction statique dans les fichiers d’en-tête peut être appelée dans d’autres fichiers.

77voto

unwind Points 181987

Est la fonction définie dans le fichier d'en-tête? De sorte que le code est donné directement dans la fonction, comme ceci:

static int addTwo(int x)
{
  return x + 2;
}

Alors que c'est juste un moyen de fournir une fonction utile à beaucoup de différents C fichiers. Chaque fichier C qui inclut l'en-tête aura son propre définition qu'il peut appeler. Bien sûr, cela déchets de la mémoire, et est (à mon avis) assez moche chose à faire, puisque le fait d'avoir le code exécutable dans un en-tête est généralement pas une bonne idée.

Rappelez-vous que #include:ing d'un en-tête est fondamentalement juste colle le contenu de l'en-tête (et tous les autres en-têtes inclus par celui-ci) dans le fichier C comme on le voit par le compilateur. Le compilateur ne sait jamais que l'un particulier de la définition de fonction est venu à partir d'un fichier d'en-tête.

Mise à JOUR: Dans de nombreux cas, c'est effectivement une bonne idée de faire quelque chose comme ci-dessus, et je me rends compte que ma réponse semble très noir-et-blanc à propos de ce qui est une sorte de trop simplifier un peu les choses. Par exemple, le code des modèles (ou utilise) fonctions intrinsèques peuvent être exprimées comme ci-dessus, et explicitement avec un mot-clé inline même:

static inline int addTwo(int *x)
{
  __add_two_superquickly(x);
}

Ici, l' __add_two_superquickly() fonction est une fiction intrinsèque, et puisque nous voulons que l'ensemble de la fonction essentiellement de compiler le bas à une seule instruction, on a vraiment envie qu'il soit incorporé. Encore, le ci-dessus est plus propre qu'à l'aide d'une macro.

17voto

sharptooth Points 93379

Il créera effectivement une fonction statique distincte portant le même nom dans chaque fichier cpp dans lequel il est inclus. La même chose s'applique aux variables globales.

10voto

RBerteig Points 23331

Comme les autres disent, il a exactement le même sens en tant que static fonction dans l' .c le fichier lui-même. C'est parce qu'il n'y a pas de différence sémantique entre .c et .h des fichiers; il est seulement l'unité de compilation composée du fichier réellement passé au compilateur (généralement nommé .c) avec le contenu de tous les fichiers nommés en #include des lignes (généralement nommé .h) insérés dans le flux comme ils sont vus par le préprocesseur.

La convention que la source C est dans un fichier nommé .c et les déclarations publiques sont dans les fichiers nommés .h n'est qu'une convention. Mais il est généralement une bonne idée. En vertu de cette convention, les seules choses qui devraient apparaître en .h des fichiers sont les déclarations de sorte que vous pouvez généralement éviter d'avoir le même symbole défini plus d'une fois dans un seul programme.

Dans ce cas particulier, l' static mot-clé fait le symbole être privé du module, donc il n'est pas un multiple de définition de conflit d'attente pour causer des ennuis. Alors, dans un sens, il est sécuritaire de le faire. Mais en l'absence d'une garantie que la fonction est insérée, vous prenez le risque que la fonction sera instancié dans chaque module est arrivé #include que le fichier d'en-tête qui, au mieux, est un gaspillage de mémoire dans le segment de code.

Je ne suis pas sûr de ce cas d'utilisation justifierait le fait à tous dans une en-tête public.

Si l' .h le fichier est généré code, et seulement inclus dans un seul .c le fichier, puis personnellement, je ne nommez le fichier d'autre chose que d' .h de souligner qu'il n'est pas réellement un public d'en-tête à tous. Par exemple, un utilitaire qui convertit un fichier binaire dans un initialisé définition de la variable peut écrire un fichier qui est destiné à être utilisé par #include et pourrait très bien contenir un static déclaration de la variable, et peut-être même static définitions de accesseur ou d'autres fonctions de l'utilitaire.

1voto

mawigator Points 11

Il est utile dans certaines bibliothèques "en-tête seulement" avec de petites fonctions inline. Dans ce cas, vous voulez toujours faire une copie de la fonction, ce qui n’est pas mauvais. Cependant, cela vous donne un moyen facile d'insérer des parties d'interface et d'implémentation distinctes dans le fichier d'en-tête unique:

 // header.h

// interface part (for user?!)
static inline float av(float a, float b);

// implementation part (for developer)
static inline float av(float a, float b)
{
    return (a+b)/2.f;
}
 

La bibliothèque mathématique des vecteurs Apple dans le cadre GLK utilise une telle construction (par exemple, GLKMatrix4.h).

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