Les en-têtes C ++
Si j'ai A.CPP et AH ainsi que BH, CH, DH P>
Dois-je faire: P>
dans AH: P> xxx pré>
en A.CPP: p> ou b> p> en A.CPP: P> #include "A.h"
#include "b.h"
#include "c.h"
#include "d.h"
6 Réponses :
Préfère non inclure les en-têtes dans d'autres en-têtes - il ralentit la compilation et les lées à une référence circulaire p>
@MGD - Si j'ai une en-tête qui compte 10 inclut et que la source était différente, devrions-je simplement déplacer l'inclinaison de l'en-tête à la source afin que la source ait 20 inclus?
Voir la réponse plus complète d'Alex. Une exception à cet égard est une exception si vous avez des en-têtes précompilés, vous incluez dans ce cas toutes les en-têtes de plate-forme / cadre / système d'exploitation qui ne changeront jamais dans un seul fichier et incluent que partout
Il n'y aurait pas de problèmes de performance, tout cela fait à la compilation, et vos en-têtes doivent être configurés afin qu'ils ne puissent pas être inclus plus d'une fois. P>
Je ne sais pas s'il y a une façon standard de le faire, mais je préfère inclure tous les en-têtes dont j'ai besoin dans des fichiers source et les inclure dans les en-têtes si quelque chose dans l'en-tête en a besoin (par exemple, un TapeDef d'un autre en-tête) P>
@Jeff - Ah Droite, les articles de l'en-tête pourraient en avoir besoin. Mais ne pourraient-ils pas l'obtenir si tous les en-têtes sont dans le fichier source?
Vous ne devez inclure que ce qui est nécessaire pour compiler; L'ajout d'une inclusion inutile vous fera mal à vos temps de compilation, en particulier dans de grands projets.
Chaque fichier d'en-tête doit pouvoir compiler proprement à sa propre position - c'est-à-dire que si vous avez un fichier source qui n'inclut que cet en-tête, il devrait compiler sans les erreurs. Le fichier d'en-tête ne doit pas inclure plus que nécessaire pour cela. P>
Essayez d'utiliser autant que possible les déclarations avant que possible. Si vous utilisez une classe, mais le fichier d'en-tête ne traite que des pointeurs / références aux objets de cette classe, il n'est pas nécessaire d'inclure la définition de la classe - utilisez simplement une déclaration en avant: P>
class SomeClass; // Can now use pointers/references to SomeClass // without needing the full definition
@Adam - Avez-vous un exemple de déclarations avant et quand il est approprié d'utiliser et quand non?
Très bon conseil. Je recommanderais également que le fichier .C associé à un .h inclut le .h comme le premier inclus, toujours. C'est pour vous assurer que tous vos fichiers .h peuvent toujours compiler eux-mêmes (au lieu de s'appuyer sur l'ordre incluant dans votre fichier .C).
+1 Pour la dernière partie, j'ai déjà toujours inclus le fichier d'en-tête.
Vous pouvez également utiliser une déclaration à terme si vous retournez soméclass code> par valeur.
Les demandeurs font également référence à @Frerichraabe Réponse ci-dessous.
Oui, le fichier d'en-tête lui-même devrait être autonome. Il devrait contenir toutes les dépendances dont il a besoin.
Quel Adam Rosenfield vous a dit que vous êtes sur place. Un exemple de lorsque vous pouvez utiliser une déclaration à terme est la suivante:
#ifndef A_H_ #define A_H_ #include "D.h" class B; //forward declaration class C; //forward declaration class A { B *m_pb; //you can forward declare this one bacause it's a pointer and the compilier doesn't need to know the size of object B at this point in the code. include B.h in the cpp file. C &m_rc; //you can also forware declare this one for the same reason, except it's a reference. D m_d; //you cannot forward declare this one because the complier need to calc the size of object D. }; #endif
(J'espère que cela s'appuie, je ne l'ai pas testé lol. Faites-moi savoir si vous avez un problème avec cela).
La pratique clé ici est d'avoir autour de chaque fichier foo.h un protège tel que: Cela empêche les inclusions multiples, avec des boucles et toutes ces horreurs de ce standard. Une fois que vous assurez que chaque fichier Include est ainsi gardé, les spécificités sont moins importantes. P> J'aime un principe de guidage Adam Exprime: Assurez-vous que si un fichier source comprend simplement Vice versa, un fichier source doit inclure les en-têtes à partir desquels il nécessite quelque chose (macros, déclarations, etc.), Si vous utilisez des cours par valeur, hélas, vous avez besoin de tous les détails de la classe de la classe dans certains ah code> , il n'aura pas inévitablement des erreurs dus à
ah code> supposer d'autres fichiers ont été incluses avant - par exemple Si
ah code> nécessite
BH code> pour être inclus auparavant, il peut et devrait simplement inclure BH même (les gardes feront une noopité si bh était déjà em> Inclus précédemment) p>
.h code> vous inclut. Mais pour certaines utilisations via des références ou des pointeurs, juste un
SIC de classe nue; code> suffira. Par exemple, toutes les autres choses étant égales, si la classe A peut vous échapper avec un pointeur em> à une instance de classe B (c.-à-d. Un membre
classe B * my_bp; code> plutôt qu'un membre plutôt qu'un membre
classe b * my_b; code>) Le couplage entre les fichiers inclus peut être faiblement affaibli (réduisant beaucoup de recompilation) - par exemple
bh code> pourrait avoir un peu plus que
la classe B; code> pendant que tous les détails de gory sont dans
b_impl.h code> qui est inclus uniquement par les en-têtes que vraiment em> besoin de ... p> p>
Étant donné que foo.h sera toujours lu à chaque fois qu'il est inclus, ce n'est pas vraiment un non-op. Ce serait un non-op si vous l'avez fait: #Ifndef _foo_h #include "foo.h" #undif
Ouais, mais cela polluerait toute inclusion dans la non-réadapabilité. À toutes fins utiles et à des fins multiples figurent dans le cache du système de fichiers. Il n'y a donc pas de performance dans "y compris" "y compris" et il s'agit certainement d'un non-op du point de vue de la sémantique, ce qui est ce qui est vraiment questions.
Réponse: Laissez raisonnement: le code MOINS est inclus dans les fichiers d'en-tête, moins vous aurez probablement besoin de Pour recompiler le code qui utilise le fichier d'en-tête après avoir changé quelque part. S'il y a beaucoup de en utilisant Déclarations avant Dans la mesure du possible dans vos fichiers d'en-tête, vous réduisez le couplage des fichiers source et rendez ainsi la construction plus rapide. Ces déclarations à terme peuvent être utilisées dans de nombreuses situations que vous pourriez penser. En règle générale, vous n'avez besoin que du fichier d'en-tête vous faites pas em> besoin d'inclure la déclaration de considère cette déclaration de classe; Lequel des fichiers inclus pour Vous avez juste besoin du fichier incluant pour le type ah code> Inclure
BH code>,
ch code> et
dh code> uniquement s'il est nécessaire de faire réussir la construction . La règle de base est la suivante: n'incluez que autant de code dans un fichier d'en-tête si nécessaire. Tout ce qui n'est pas immédiatement nécessaire dans
ah code> doit être inclus par
A.CPP code>.
#include code> des références entre différents fichiers d'en-tête, la modification de l'un d'entre eux nécessitera une reconstruction tous les fichiers em> qui incluent le fichier d'en-tête modifié - Récursel. Donc, si vous décidez de toucher un fichier d'en-tête Toplevel, cela pourrait reconstruire d'énormes parties de votre code. P>
t.h code> (qui définit un type
t code>) si vous p>
t code> (Remarque, ce n'est pas em> notamment déclarant un pointeur à-
t code>). LI >
t code>. li>
ol>
t code> si votre fichier d'en-tête juste p>
t code>. li>
t code> par le pointeur, la référence ou la valeur. LI>
t code>. li>
ol>
A code>,
b code> et
c code> Avez-vous vraiment besoin d'inclure?: p>
C code>, en raison de la variable de membre
m_c code>. Vous pouvez souvent supprimer cette exigence également en ne déclarant pas vos variables de membre directement, mais utilisez un Pointeur opaque pour masquer toutes les variables de membre dans une structure privée, de sorte qu'elles ne se présentent plus dans le fichier d'en-tête. p> p>
Vous mélangez A, B et C avec X, Y et Z dans votre exemple.
@Bill: Vous avez raison, j'ai ajusté l'exemple pour dire A, B, c maintenant.
@Frerichraabe réponse parfaite. +1 pour le "raisonnement:" partie.