Il sont quelques raisons valables pour le fractionnement d'en-tête/mise en œuvre et compilation séparée:
1. Cela peut être une exigence d'emploi - par exemple, vous fournir une bibliothèque binaire + tête à quelqu'un, ou votre collègues sont trop conservateurs pour accepter quoi que ce soit d'autre.
2. Son encore nécessaire pour développer de très grands projets (disons,> 10M de source), parce que la reconstruction de l'application entière après chaque modification deviendrait douloureuse. (Mais il devrait encore être correct de compiler quelque chose comme jpeglib ou zlib en un seul module)
3. On pense qu'il est plus facile d'utiliser les fichiers d'en-tête comme référence, pour regarder up fonctions et autres. (Mais normalement son mieux pour écrire une documentation appropriée, contrairement à les en-têtes, des bugs dans la documentation sont moins susceptibles d'affecter votre programme)
En outre, il sont des raisons beaucoup plus pour ne pas l'utiliser plus:
1. Vous seriez aime éviter de maintenir le code en double.
2. Les méthodes de classe n'ont pas besoin de déclarations directes
3. Les modèles ne peuvent être déclarés dans les en-têtes de toute façon que
4.Les cas dans lesquels vous n'avez pas besoin de fonction inline sont en fait assez rares, c'est-à-dire appeler de grandes fonctions plusieurs fois dans une boucle serrée, mais il ya noinline attibutes et PGO pour cela. Sinon, l'inlining améliore la vitesse. Et pour ce qui est du gonflement du code, la plupart des bibliothèques sont déjà énormes.
5. Dans l'ensemble, les programmes compilés en tant que source unique sont plus rapides et plus petits, parce que le compilateur peut faire un meilleur travail.
6. Sans les en-têtes, la source serait souvent deux fois plus petite, et le compilateur serait en mesure de vérifier correctement la syntaxe, donc vous ne pourrez pas lier accidentellement un prototype de fonction cdecl "C" externe à une variable comme mise en œuvre. De manière générale, ce serait plus portable, car les différents éditeurs de liens ont des idées différentes sur la correspondance des noms.
7. Son allocation bizarre mais dynamique est fréquemment utilisée uniquement en raison du style d'en-tête - les dépendances peuvent être résolues automatiquement en définissant tous les détails dans une seule classe, mais les gens préfèrent utiliser des pointeurs vers des déclarations de classe partielle à la place (puis chasse les fuites de mémoire).
Maintenant, quelques points de bonus pour les modules d'objets distincts:
4. Statistiques PGO en gcc sont générés par module d'objet, qui semble être le seul moyen de « référence » quelques différents modes de fonctionnement avec un seul exécutable.
5. Il est possible de compiler différents modules avec différentes options de compilateur pour optimiser la vitesse. Il existe également des extensions de compilateur, mais elles ne sont pas très fiables.
6. Parfois, un compilateur peut faire quelque chose de bizarre à une autre partie du code lorsque vous modifiez quelque chose - mais généralement, il ne peut pas se propager en dehors d'un module d'objet.
+1 J'aime beaucoup votre réponse. Mais par curiosité, que pensez-vous des modèles? J'ai vu beaucoup de code de modèle soit inclure des en-têtes "inline" supplémentaires ou être un gâchis géant de méthodes. – GWW
@GWW: les templates sont instanciés pour chaque combinaison de types, ce qui les rend très rapides et puissants mais très dépendants du code client. Tout au long de l'histoire C++ personne n'a trouvé un bon moyen d'éviter d'avoir à exposer "l'implémentation" via les en-têtes. # inclure un autre fichier peut parfois aider à séparer l'API, tout comme les définitions de fonctions après les déclarations de classe/struct, mais les résultats optimaux varient selon plusieurs facteurs (longueur de la fonction, quantité et style de documentation, complexité, nombre/compétences des utilisateurs clients par rapport aux responsables de l'implémentation). It * is * messy :-) –
L'éditeur de liens n'est pas obligé de vérifier si deux instances d'une définition de classe sont identiques (et je ne connais pas un éditeur de liens qui le fait). S'ils ont le même nom, il * suppose * qu'ils sont identiques et supprime l'un ou l'autre. Le fardeau est toujours sur le programmeur pour ne pas violer l'ODR. – jalf