29 votes

Gérer les déclarations à terme

Il est bien connu que la déclaration est préférable à l'utilisation de #inclut dans les fichiers d'en-tête, mais quelle est la meilleure façon de gérer les déclarations de l'avant?

Pendant un moment, j'étais en ajoutant manuellement pour chaque fichier d'en-tête l'en avant les déclarations qui ont été requis par ce fichier d'en-tête. Cependant, je me suis retrouvé avec un tas de fichiers d'en-tête de répéter la même demi-douzaine d'avant déclarations, qui semble redondant, et le maintien de ces répété listes obtenu d'être un peu fastidieux.

Déclaration des typedefs (par exemple, struct SensorRecordId; typedef std::vector<SensorRecordId> SensorRecordIdList;) est également un peu beaucoup à dupliquer sur plusieurs fichiers d'en-tête.

Alors j'ai fait un ProjectForwards.h le fichier qui contient l'ensemble de mon avant déclarations et compris que là où cela était nécessaire. Au début, cela semblait être une bonne idée - un peu moins de redondance, et beaucoup plus facile à l'entretien des typedefs. Mais maintenant, en tant que résultat de l'utilisation de ProjectForwards.h si lourdement, à chaque fois que j'ajoute une nouvelle classe, j'ai reconstruire le monde, ce qui ralentit le développement.

Alors, quelle est la meilleure façon de gérer les déclarations de l'avant? Dois-je mordre la balle et répéter des déclarations de l'avant à travers de multiples sous-systèmes? Continuer avec l' ProjectForwards.h approche? Essayez de fractionner ProjectForwards.h plusieurs SubsystemForwards.h fichiers? Une autre solution je suis dominant?

7voto

Michael Kristofik Points 16035

Il sonne comme ces classes sont assez communs à une grande partie de votre projet. Vous pouvez essayer certains de ces:

  • Faites de votre mieux pour briser ProjectForwards.h en plusieurs fichiers comme vous l'avez suggéré. Assurez-vous que chaque sous-système ne reçoit que les déclarations qu'il a vraiment besoin. Si rien d'autre, ce processus va vous forcer à réfléchir sur le couplage entre votre sous-systèmes et vous pourriez trouver des moyens de la réduire. Ce sont toutes de bonnes mesures en vue d'éviter la sur-compilation.

  • Imiter <iosfwd>. Demandez à chaque commune de la classe ou d'un module de fournir sa propre avant-inclure l'en-tête qui fournit les noms de classe et de toute commodité typedefs. Ensuite, vous pouvez #include partout. Oui, vous allez répéter la liste de beaucoup de choses, mais pensez-y de cette façon: personne ne se plaint #y compris <vector>, <string>, et <map> dans six lieux différents dans leur code.

  • Utilisation Pimpl plus souvent. Cela aura un effet similaire à ma suggestion précédente, mais nécessitent plus de travail de votre part. Si vos interfaces sont stables, alors vous pouvez offrir les typedefs dans les en-têtes et #inclure directement.

6voto

CashCow Points 18388

En général:

  1. Ayez un fichier de transfert pour les utilisateurs de votre module. Cela déclarera uniquement les classes qui apparaissent dans le cadre de l'API.

  2. Si vous avez couramment utilisé des transferts dans votre implémentation, vous pouvez avoir un fichier de transferts basé uniquement sur l'implémentation.

  3. Vous n'avez probablement pas besoin d'une déclaration directe pour chaque classe que vous utilisez.

3voto

Tod Points 3501

Avoir fait beaucoup de brun maintenance sur le terrain, je n'ai jamais été friand de comprend qui ne font rien, mais inclure d'autres fichiers ou avoir de la déclaration. Je préfère juste les avoir dans le fichier d'en-tête. Vous pouvez réduire la vitesse de frappe avec l'utilisation de modèles si vos outils de les soutenir. Vous pourriez écrire un modèle qui se développe dans le texte de votre choix. Je serais probablement inclure quelque chose pour le faire ressortir comme

///Begin Forwarding
...
///End Forwarding

Qui le rendent facile à saisir et remplacez-les si vous modifiez le modèle. Si vous êtes plus à l'aise avec des outils comme grep, vous pouvez automatiser la mise à jour à partir d'une ligne de commande. Il serait probablement être simple à écrire un script qui permettrait de mettre à jour tous les fichiers, ou uniquement les fichiers passés sur la ligne de commande. Juste une pensée.

3voto

Dan O Points 1669

Je n'ai jamais vu un "en-tête de l'attaquant déclare" qu'était réellement utile (personne ne l'utilise), n'est pas de devenir rapidement obsolètes (plein de trucs que personne ne l'utilise), et n'était pas une itération de goulot d'étranglement (a touché le déclarer avant d'en-tête? tout recompiler!). Généralement, ils développent tous les trois problèmes.

La base de votre problème est la conception du système. Ces sous-systèmes que vous avez mentionné doit probablement y compris l'en-tête des fichiers qui définissent le type dont ils ont besoin pour prendre en entrée ou en sortie. En brisant les types qui sont utilisés par de multiples sous-systèmes dans leur propre fichier d'en-tête, vous allez trouver un bel équilibre entre l'isolement et efficace de l'interopérabilité entre les sous-systèmes.

2voto

herzbube Points 3034

Je ne pense pas qu'il y est une seule "meilleure" solution, chacun a ses propres avantages et inconvénients. Même si c'est plus de travail, personnellement, je préfère le "chaque en-tête de fichier à sa propre déclaration", pour les raisons suivantes:

  • C'est aussi maigre qu'elle peut l'être: Pas d'autres fichiers qui doivent être trouvées et analysées.
  • Pas de confusion: en regardant Simplement le fichier d'en-tête que vous voyez exactement quels types de besoins.
  • Pas de superflu de l'espace de noms de la pollution. Si vous collectez de l'avant déclarations en ProjectForwards.h le fichier, ce fichier contient la somme de toutes les déclarations nécessaires par l'ensemble de ses consommateurs. Donc, si un seul consommateur a besoin d'une certaine déclaration, toutes les autres vont en hériter, trop.

Si ces arguments ne sont pas convaincants, peut-être parce qu'ils sont trop puriste :-), alors je suggère de suivre la voie du milieu de fractionnement ProjectForwards.h.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X