Reduce the number of #include files in header files. It will reduce build times. Instead, put include files in source code files and use forward declarations in header files.
J'ai lu ça ici. http://www.yolinux.com/TUTORIALS/LinuxTutorialC++CodingStyle.html .
Il indique donc si une classe (classe A) dans le fichier d'en-tête n'a pas besoin d'utiliser la définition réelle d'une classe (classe B). À ce moment, nous pouvons utiliser la déclaration directe au lieu d'inclure le fichier d'en-tête particulier (classe B).
Question: Si la classe (classe A) dans l'en-tête n'utilise pas la définition réelle d'une classe particulière (classe B), alors comment la déclaration directe contribue à réduire le temps de compilation?
la source
vehicle.h
,bus.h
,toybus.h
.vehicle.h
inclure parbus.h
etbus.h
inclure partoybus.h
. donc si je changebus.h
. le compilateur s'ouvre-t-il et analyse-vehicle.h
t-il à nouveau? le compile-t-il à nouveau?#pragma once
ou#ifndef __VEHICLE_H_
tapez des déclarations dans les fichiers d'en-tête afin d'empêcher que ces fichiers soient inclus plusieurs fois (ou utilisés plusieurs fois au moins dans le cas d'ifndef).car alors A.hpp n'a pas besoin de #inclure B.hpp
donc A.hpp devient
donc quand A.hpp est inclus alors B.hpp n'est pas implicitement inclus et tous les fichiers qui ne dépendent que de A.hpp n'ont pas besoin d'être recompilés à chaque fois que b.hpp change
la source
N'oubliez pas que le préprocesseur C / C ++ est une étape de traitement distincte, purement textuelle. La
#include
directive extrait le contenu de l'en-tête inclus et le compilateur doit l'analyser. De plus, la compilation de chacun.cpp
est complètement séparée, donc le fait que le compilateur vient d'être analyséB.h
lors de la compilationB.cpp
ne l'aide pas du tout quand il en a besoin à nouveau lors de la compilationA.cpp
. Et encore lors de la compilationC.cpp
. EtD.cpp
. Etc. Et chacun de ces fichiers doit être recompilé si l'un des fichiers qu'il contient a changé.Disons que la classe
A
utilise la classeB
et les classesC
etD
utilise la classeA
, mais n'a pas besoin de manipulerB
. Si la classeA
peut être déclarée avec juste une déclaration directe deB
, alors elleB.h
est compilée deux fois: lors de la compilationB.cpp
etA.cpp
(car elleB
est toujours nécessaire dansA
les méthodes de).Mais quand
A.h
comprendB.h
, il est compilé quatre fois lors de la compilation-B.cpp
,A.cpp
,C.cpp
etD.cpp
comme plus tard , deux sont maintenant indirectementB.h
aussi.De plus, lorsque l'en-tête est inclus plusieurs fois, le préprocesseur doit toujours le lire à chaque fois. Il sautera le traitement de son contenu à cause des protections
#ifdef
, mais il le lit toujours et doit rechercher la fin de la protection, ce qui signifie qu'il doit analyser toutes les directives du préprocesseur à l'intérieur.(Comme mentionné dans l'autre réponse, les en-têtes précompilés tentent de contourner ce problème, mais ils sont leur propre boîte de vers; en gros, vous pouvez raisonnablement les utiliser pour les en-têtes du système et uniquement si vous n'en utilisez pas trop, mais pas pour en-têtes de votre projet)
la source
Une déclaration directe est beaucoup plus rapide à analyser qu'un fichier d'en-tête entier qui lui-même peut inclure encore plus de fichiers d'en-tête.
De plus, si vous modifiez quelque chose dans le fichier d'en-tête pour la classe B, tout ce qui comprend cet en-tête devra être recompilé. Avec une déclaration directe, cela ne peut être que le fichier source dans lequel l'implémentation de A réside. Mais si l'en-tête de A incluait réellement l'en-tête de B, tout y compris
a.hpp
sera recompilé également, même s'il n'utilise rien de B.la source