Je suis un peu nouveau pour le développement de logiciels à grande échelle en C++ et je me demandais du côté design des choses.
Je lisais cette question , et je pensais que, dans l'ensemble, une fois que nous avons passé des définitions constantes et d'autres questions triviales, C++ Les fichiers d'en-tête ne sont que des définitions d'API :
Ils définissent ce que les autres programmeurs (ou vous-même d'autres modules) seront en mesure d'utiliser (classes, fonctions publiques), mais aucune classe ou fonction privée ne doit être définie. C'est comme si le fichier d'en-tête définit les abstractions (interfaces ...) et le fichier source implémente-le. Une fois le fichier source compilé, les détails de la mise en œuvre sont cachés à l'écart et restent les en-têtes disponibles publiquement définissant ce que le module peut faire.
J'ai ressenti cette vision de la séparation des fichiers d'en-tête/source était beaucoup plus facile à comprendre et à suivre que les explications habituelles, car vous pouvez simplement penser "XXX
être disponible au public de matériel d'API, ou est-ce un détail de saucisse être caché dans un fichier source non divulgué? "
Mon modèle mental des fichiers d'en-tête est-il approximativement correct? Qu'est-ce que j'ai raté ?
Ce n'est pas un mauvais modèle mental à utiliser comme guide, mais malheureusement pour des raisons historiques/techniques, C++ Les en-têtes de confluent l'interface et la mise en œuvre de manière à ce que ce modèle mental simple ne capture pas complètement.
Afin de prendre de bonnes décisions de conception physique lorsque les choses deviennent un peu plus complexes, il est généralement nécessaire de comprendre la manière dont les en-têtes fonctionnent en C++ à un niveau plus détaillé.
Pour donner un exemple: à partir de votre affichage de l'API, un fichier d'en-tête ne doit pas inclure la définition d'une classe de mise en œuvre privée. Dans la pratique Cependant, ces définitions de classe apparaissent souvent dans un fichier d'en-tête puisque le compilateur devra connaître leur taille si elles sont contenues dans des classes publiques. Des techniques existent pour briser ce type de dépendance, mais ils imposent généralement un coût en termes de complexité, de performance ou des deux. Comprendre quand il est approprié d'utiliser une de ces techniques nécessite une compréhension plus profonde de la façon dont les en-têtes fonctionnent en C++.
À peu près, il y a peu de différence entre un fichier d'en-tête et une interface utilisée par d'autres langues pour la partie principale. De toute évidence, il existe des différences de mise en œuvre en ce que l'en-tête contiendra également des informations privées, mais il est fondamentalement utilisé pour décrire les fonctionnalités de la classe ou du module.
En quelque sorte, c'est également un modèle mental de structures de données combinés à l'API afin qu'il puisse être plus utile lorsque vous faites le type de conception initiale que vous décrivez.
Idéalement, un en-tête définissant une API ne contiendrait que l'interface pure mais que c ++ n'a pas d'abi, cela n'a pas vraiment d'importance. Si vous construisez un système de niveau supérieur qui fournit une interface client pure, vous utiliserez un mécanisme différent tel qu'un IDL ou WSDL pour définir cela de toute façon.