Je sais qu'il est courant dans les projets C/C++ de placer les fichiers d'en-tête dans un répertoire tel que include
et la mise en œuvre dans un répertoire séparé tel que src
Je suis en train de jouer avec différentes structures de projets et je me demande s’il existe des raisons objectives de le faire ou s’il s’agit simplement d’une convention?
La convention en est l'une des raisons - la plupart du temps, avec une abstraction efficace, vous ne vous souciez que de l'interface et vous voulez que ce soit facile, juste de regarder les en-têtes.
Ce n'est pas la seule raison cependant. Si votre projet est organisé en modules, vous devrez probablement inclure des en-têtes dans différents modules et vous souhaitez que votre répertoire d'inclusion soit nettoyé de tous les fichiers "parasites" qu'il contient.
De plus, si vous envisagez de redistribuer votre module, vous souhaiterez probablement masquer les détails de la mise en œuvre. Vous ne fournissez donc que des en-têtes et des fichiers binaires - et la distribution des en-têtes à partir d'un seul dossier sans autre élément est plus simple.
Il y a aussi une alternative que je préfère en réalité - les en-têtes publics sont placés dans un dossier séparé (ils contiennent l'interface minimale - aucun détail sur l'implémentation n'est visible), et les en-têtes privés et les fichiers d'implémentation sont séparés (éventuellement, mais pas nécessairement). dans des dossiers séparés).
Je préfère les mettre dans le répertoire même . Raison:
Le ou les fichiers de spécification d'interface et le ou les fichiers source implémentant cette interface appartiennent à la même partie du projet. Disons que vous avez subsystemx
. Ensuite, si vous placez des fichiers subsystemx
dans le répertoire subsystemx
, subsustemx
est autonome.
S'il y a beaucoup de fichiers include, vous pouvez certainement utiliser subsystemx/include
et subsystemx/source
, mais je soutiens alors que si vous définissez la définition de class Foo
dans foo.hpp
et foo.cpp
, vous voudrez certainement les voir tous les deux (ou du moins avoir la possibilité de le faire facilement) ensemble dans une liste de répertoires. Trouver tous les fichiers liés à foo
ls foo*
Trouver tous les fichiers d'implémentation:
ls *.cpp
Trouver tous les fichiers de déclaration:
ls *.hpp
Simple et propre.
Il garde votre structure de dossiers plus propre. Les en-têtes et les fichiers source sont nettement différents et sont utilisés pour différentes choses. Il est donc logique de les séparer. De ce point de vue, la question est fondamentalement la même que " pourquoi les fichiers sources et la documentation sont-ils placés dans des dossiers différents "? L'ordinateur est extrêmement agnostique à propos de ce que vous mettez dans des dossiers et de ce que vous n'aimez pas. Les dossiers ne sont pour la plupart qu'une abstraction pratique en raison de la façon dont nous, les êtres humains, analysons, stockons et rappelons les informations.
Il y a aussi le fait que les fichiers d'en-tête restent utiles même après avoir construit , c'est-à-dire que si vous construisez une bibliothèque et que quelqu'un souhaite utiliser cette bibliothèque, ils auront besoin des fichiers d'en-tête - pas des fichiers sources - - cela permet donc de regrouper ces fichiers d'en-tête - récupérer les éléments dans bin
et les éléments dans include
et ne pas avoir à passer au crible src
- beaucoup plus facilement.
Outre l'utilité (discutable?) De garder les choses en ordre, utile dans d'autres projets, etc., il existe un avantage très neutre et objectif: compiler le temps.
En particulier, dans un grand projet avec tout un tas de fichiers, en fonction des chemins de recherche pour les en-têtes (fichiers .c/.cpp utilisant #include "headername.h"
plutôt que #include "../../gfx/misc/something/headername.h"
et que le compilateur a transmis les bons paramètres pour pouvoir l'avaler), vous réduisez considérablement le nombre d'entrées devant être analysées par le compilateur à la recherche du bon en-tête. Comme la plupart des compilateurs commencent séparément pour chaque fichier compilé, ils doivent lire la liste des fichiers sur le chemin d'inclusion et rechercher les bons en-têtes pour chaque fichier compilé. S'il y a beaucoup de fichiers .c, .o et d'autres fichiers non pertinents sur le chemin d'inclusion, la recherche de l'include prend proportionnellement plus de temps.
En bref, quelques raisons:
Consultez l'article Organisation des fichiers de code en C et C++ qui l'explique bien.