9
votes

C ++: inconvénients pour écrire des classes entières dans des fichiers d'en-tête pour de petits projets?

juste une question de style ...

Je suis un jeu de jeu très indie travaillant par moi-même et j'ai développé ce que j'ai dit, c'est une mauvaise habitude d'écrire des classes entières dans mes en-têtes. Certains des avantages que je connais des combos de fichiers .H / .CPP sont-ils autorisés à ce que le code soit divisé en morceaux de compilation qui n'auront pas besoin de recompanter tant qu'ils restent inchangés. Et permet de scinder l'interface de la mise en œuvre.

Cependant, aucune de ces choses ne concerne aucun avantage pour moi, car j'ai tendance à favoriser ma mise en œuvre sur place où je peux facilement l'améliorer, le changer, le lire. Et mes temps de compilation sont presque instantanés (2-4 secondes, 15 si je mettais à jour SFML ou Box2D vers leurs dernières versions et ils ont également besoin de recompiler également)

Codage comme ça m'a été sauvé une quantité de temps très perceptible que je pense, et comme il y a moins de fichiers, mon code se sent moins "écrasant" pour moi.

Mais à la lumière de cela, et en général, y a-t-il une raison convaincante de suivre le configuration "File.cpp" pour chaque configuration "File.H" pour un petit projet où la compilation de l'heure et de l'interface / la séparation de la mise en œuvre ne sont-elles pas des priorités?


7 commentaires

Que mettez-vous dans vos fichiers .C ++ , hors de curiosité?


... Doh. Je viens de remarquer une question connexe presque exactement comme celle-ci. Je me demande si c'est considéré comme une bonne étiquette pour supprimer des questions répétitives? Ou mauvais. Je déteste penser à une réponse que quelqu'un écrit pourrait être supprimé aussi, haha


@Clairvoire: postez un lien avec lui et nous pouvons fermer celui-ci comme un duplicata.


@Greg: Habituellement, ce sont des méthodes de classe sous la forme de void classname :: méthodname (liste de paramètres *) {dostuff (); }; J'ai tendance à faire la même chose dans le fichier d'en-tête pour des fonctions non inlinées, mais allant entre deux fichiers pour le faire est une douleur parfois.


@James: Stackoverflow.com/questions/3810440 / C-Whis-Class-in-h-file C'est beaucoup plus concis que ma question, c'est sûr, haha


Ce n'est pas vraiment une question en double: votre question est beaucoup plus spécifique. Je pense que votre question est bien comme.


@Clairvoire: Merci d'avoir cherché chercher et des doublons potentiels.


3 Réponses :


6
votes

Y a-t-il une raison convaincante de suivre le "fichier.cpp" pour chaque configuration "File.H" pour un petit projet où la compilation et la séparation de l'interface / de la mise en œuvre ne sont pas des priorités?

Nope; Il n'y a rien de mal à définir des cours et des fonctions dans les fichiers d'en-tête, surtout pas dans de petits projets où les temps de compilation ne sont pas une préoccupation.

Pour ce que ça vaut la peine, mon projet de hobby actuel en cours contient 33 fichiers d'en-tête et un seul fichier .CPP (non compris les tests d'unités). Qui est en grande partie dû à tout ce étant un modèle, cependant.

Si vous avez un énorme projet logiciel ou si vous devez encapsuler votre code dans une bibliothèque et avez besoin de la modularité, il peut être logique de scinder le code d'un fichier d'en-tête. Si vous souhaitez masquer certains détails de la mise en œuvre (par exemple, si vous avez une en-tête laideuse que vous ne voulez pas inclure ailleurs dans votre projet - les en-têtes Winapi, par exemple), il est logique de scinder le code dans un fichier source séparé cacher ces détails. Sinon, cela peut simplement être beaucoup de travail pour pas beaucoup de gain.


5 commentaires

D'accord, merci! Aha, je me demandais si c'était vraiment aussi simple. Presque tous les guides de style que j'ai lus ont fait un point de faire chaque fichier d'en-tête et de fichier .cpp dans ce format.


Edit: Et oui, cela vaut un peu! Il est bon de savoir que je ne casse pas une règle fondamentale de C ++ à tout le moins, si d'autres personnes le font dans leurs propres travaux personnels aussi


Les guides de style disent que parce que c'est la règle. L'affaire décrite ici est une exception. Toujours enseigner à la règle d'abord la règle parce qu'à un moment donné, l'enseignement arrête d'écouter. Cela dit, ce que vous voulez éviter est le motif d'un ancien collègue utilisé, qui utilise uniquement des en-têtes pour le code réel, puis un couplage. CPPP dans toute la chose. A pris pour toujours pour construire (80-100 fichiers), il n'a pas été associé à nos parties du système (nombre énorme d'erreurs de définition de plusieurs définitions lors du lien), il a fait make -j inutile, et chaque construire était une construction complète.


@Mike: De plus, les jours sont partis quand vous avez dû #include tout ensemble pour optimiser les opportunités d'optimisation. Les dernières versions de tous les principaux compilateurs prennent désormais une optimisation de l'ensemble du programme, qui fait l'inlinge et les conventitions d'appel personnalisées entre les unités de compilation. Bien sûr, le prix que vous payez pour retourner que l'option est des heures de liens approchant de la compile-tout-ensemble de temps de construction.


@MIKE: La convention existe pour une raison, je n'oublierai pas beaucoup. Pour un grand projet, ou un avec d'autres personnes qui y travaillent, je ferais de nombreuses choses différentes, pas seulement à quel point mes en-têtes et mes fichiers sont mis en place, haha. Comme si je cuisine pour ma famille et comment je cuisine (micro-ondes) pour moi-même.



2
votes

Je pense que la compilation du temps et de l'interface / la séparation de la mise en œuvre sont de bonnes raisons. Même si le premier n'est pas un problème actuellement, dans la plupart des projets de taille décente, cela devient un problème.

Mais, puisque vous avez demandé d'autres raisons, je pense qu'un gros est qu'il réduit les dépendances. La mise en œuvre de votre classe nécessite probablement plus de #includes que l'interface. Mais si vous mettez la mise en œuvre dans le fichier d'en-tête, vous faites glisser sur ces dépendances avec l'en-tête. Ensuite, tous les autres fichiers qui comprend cela ont également ces dépendances.

Il n'y a pas de règle unique - toutes les règles. Et certaines classes (en particulier "petites") sont probablement mieux placées entièrement dans un en-tête.


1 commentaires

Je garderai ça à l'esprit! Pour des classes particulièrement importantes avec de grandes méthodes, comme des solveurs de physique, etc., je vais faire un fichier .CPP pour eux, bien que ces classes soient rares et bien entre.



1
votes

Qu'est-ce que vous faites des sons sensibles à votre situation. Deux autres problèmes potentiels:

  • une règle de définition
  • Test

    Si vous n'avez qu'un seul fichier CPP et une douzaine d'en-têtes, vous pouvez vous permettre d'être négligents sur la règle d'une définition (en supposant que vous avez inclus des gardes). Cela pourrait vous mordre si vous trouvez un jour la nécessité de vous déplacer pour compiler / relier le projet sous forme de plusieurs unités de traduction. Cela pourrait se produire de manière non si évidente, telle que vouloir laisser les autres personnes fournir une bibliothèque à construire à l'aide de quelques-uns de vos en-têtes. Implicity (défini à l'intérieur de la classe) ou explicitement (à l'aide du mot clé) Fonctions en ligne sera OK, mais attention aux autres. Règles habituelles pour les variables, etc.

    Pour tester: il est parfois utile d'avoir au moins un fichier de jeton .CPP qui inclut le .h et se compile, tout simplement que vous obtenez un avertissement précoce si le contenu d'un en-tête ne peut pas "rester seul", probablement dû à un oublié #include. Si vous avez des fichiers de test en-tête. CPPP, alors qui tue deux oiseaux, etc. Si vous ne voulez pas de tester à ce niveau et que vous êtes heureux de nettoyer les bugs de dépendance mineurs de manière réactive, alors l'oubliez-vous.


0 commentaires