Quelles choses ne devraient absolument jamais être incluses dans un fichier d'en-tête?
Si, par exemple, je travaille avec un format standard documenté comportant de nombreuses constantes, est-ce une bonne pratique de les définir dans un fichier d'en-tête (si j'écris un analyseur syntaxique pour ce format)?
Quelles fonctions devraient aller dans le fichier d'en-tête?
Quelles fonctions ne devraient pas?
Réponses:
Quoi mettre dans les en-têtes:
#include
directives nécessaires pour rendre l'en-tête compilable lorsque celui-ci est inclus dans un fichier source.Ce qui n'appartient pas à un en-tête:
#include
Directives gratuites . Ces inclusions gratuites entraînent une recompilation de choses qui n'ont pas besoin d'être recompilées et peuvent parfois empêcher un système de compiler. Ne créez pas de#include
fichier dans un en-tête si l'en-tête lui-même n'a pas besoin de cet autre fichier d'en-tête.#include
, sujettes à modification ou trop grandes. Ces fonctions en ligne devraient avoir peu ou pas de sortants, et s’ils le sont, il devrait être localisé dans les éléments définis dans l’en-tête.Qu'est-ce qui constitue l'ensemble minimal d'
#include
énoncés?Cela s'avère être une question non triviale. Une définition de TL; DR: un fichier d’en-tête doit inclure les fichiers d’en-tête qui définissent directement chacun des types directement utilisés dans ou déclarant directement chacune des fonctions utilisées dans le fichier d’en-tête en question, sans rien inclure d'autre. Un pointeur ou un type de référence C ++ ne constitue pas une utilisation directe. les références en aval sont préférées.
Il y a une place pour une
#include
directive gratuite , et cela se fait dans un test automatisé. Pour chaque fichier d'en-tête d'un progiciel, je génère et compile automatiquement les éléments suivants:La compilation doit être propre (c.-à-d. Exempte de tout avertissement ou erreur). Des avertissements ou des erreurs concernant des types incomplets ou inconnus signifient que le fichier d’en-tête à tester comporte des
#include
directives manquantes et / ou des déclarations de transfert manquantes. Remarque: le fait que le test réussisse ne signifie pas que le jeu de#include
directives est suffisant, encore moins minimal.la source
En plus de ce qui a déjà été dit.
Les fichiers H doivent toujours contenir:
Les fichiers H ne doivent jamais contenir:
static
.(Je dirais également qu'il n'y a jamais de raison d'utiliser des variables globales / externes non constantes, où que ce soit, mais c'est une discussion pour un autre article.)
la source
Je ne dirais probablement jamais jamais, mais les instructions qui génèrent des données et du code lorsqu’elles sont analysées ne doivent pas figurer dans un fichier .h.
Les macros, les fonctions en ligne et les modèles peuvent ressembler à des données ou à du code, mais ils ne génèrent pas de code lors de leur analyse, mais plutôt lorsqu'ils sont utilisés. Ces éléments doivent souvent être utilisés dans plus d'un fichier .c ou .cpp, ils appartiennent donc au fichier .h.
À mon avis, un fichier d'en-tête devrait avoir l'interface pratique minimale avec un .c ou .cpp correspondant. L'interface peut inclure #defines, class, typedef, définitions de structure, prototypes de fonctions et définitions externes moins préférées pour les variables globales. Toutefois, si une déclaration est utilisée dans un seul fichier source, elle devrait probablement être exclue du fichier .h et figurer à la place dans le fichier source.
Certains peuvent ne pas être d'accord, mais mes critères personnels pour les fichiers .h sont qu'ils incluent tous les autres fichiers .h dont ils ont besoin pour pouvoir compiler. Dans certains cas, il peut s'agir de nombreux fichiers. Nous disposons donc de méthodes efficaces pour réduire les dépendances externes, telles que les déclarations forward aux classes, qui nous permettent d'utiliser des pointeurs sur les objets d'une classe sans inclure ce qui pourrait être une grande arborescence de fichiers d'inclusion.
la source
Le fichier d'en-tête doit avoir l'organisation suivante:
Les fichiers d'en-tête ne doivent jamais contenir de définitions d'objet, mais uniquement des définitions de type et des déclarations d'objet.
la source
Les instructions qui génèrent des données et du code au fur et à mesure de leur analyse ne doivent pas figurer dans un
.h
fichier. En ce qui concerne mon point de vue, un fichier d’en-tête ne devrait avoir que l’interface pratique minimale avec un.c
ou.cpp
.la source