it-swarm.dev

Que faire si je déteste les fichiers d'en-tête C ++?

J'étais toujours confus au sujet des fichiers d'en-tête. Ils sont si étranges: vous incluez un fichier .h qui n'inclut pas .cpp mais .cpp sont en quelque sorte compilés aussi.

Récemment, j'ai rejoint un projet d'équipe et, bien sûr, les deux .h et .cpp sont utilisés.
Je comprends que c'est très important, mais je ne peux pas vivre avec le copier-coller de chaque déclaration de fonction dans chacune des multiples classes que nous avons.

Comment gérer efficacement la convention des 2 fichiers?
Existe-t-il des outils pour vous aider ou changer automatiquement un fichier qui ressemble à l'exemple ci-dessous en .h et .cpp? (spécifiquement pour MS VC++ 2010)

class A
{
...
    Type f(Type a,Type b)
    {
        //implementation here, not in another file!
    }
...
};

Type f(Type a)
{
     //implementation here
}
...
25
Oleh Prypin

Vous pouvez utiliser Lzz . Il s'agit d'un outil en ligne de commande qui prend des déclarations écrites dans une syntaxe C++ et génère l'en-tête et les fichiers source.

3
Mario Becerra

Rédaction de C++ plus convivial

En C++, vous n'avez pas pour utiliser les en-têtes du tout. Vous pouvez définir l'objet entier dans un seul fichier comme vous le feriez avec C # ou Java. Les développeurs C ne conserveront généralement les appels externes que dans un fichier d'en-tête. Tous les appels internes seraient définis dans le fichier .c. De la même manière, vous pouvez réserver vos fichiers C++ .h pour les classes/interfaces (classes abstraites virtuelles pures)/etc. qui sont destinés à être partagés en dehors de la DLL. Pour les classes/structures/interfaces internes, etc., vous incluriez simplement le fichier .cpp dont vous avez besoin:

#include<myclass.cpp>

Cela ne semble pas être l'approche la plus populaire, mais c'est du C++ légal. Ce serait certainement une possibilité pour tout votre code interne. Cela permet au code interne et à l'ensemble de classes de changer beaucoup plus radicalement tout en offrant une interface plus stable pour le code en dehors de votre bibliothèque/exécutable avec lequel interagir.

Le fait d'avoir toute votre classe dans un seul fichier vous permettra de faire plus facilement ce que vous voulez. Cela ne résoudra pas le problème de renommer une méthode et d'avoir à rechercher chaque endroit où cette méthode est appelée, mais cela vous assurera d'avoir des messages d'erreur plus intelligibles. Rien de pire que d'avoir votre en-tête déclarer une méthode dans un sens, mais vous l'implémentez différemment. L'autre code qui appelle le fichier d'en-tête se compilera correctement et vous obtiendrez une exception de lien, tandis que le fichier d'implémentation sera celui qui se plaint que la méthode n'a pas été définie. Lorsque vous définissez chaque méthode en place (dans la déclaration de classe réelle), vous obtiendrez le même message d'erreur quel que soit le fichier qui l'inclut.

Vous pouvez également consulter cette question: Bons outils de refactoring pour C++

Comment C/C++ résout les fichiers d'en-tête/d'implémentation

Au niveau C de base (et C++ est construit sur cette base), les fichiers d'en-tête déclarent la promesse d'une fonction/structure/variable qui est suffisante pour permettre à un compilateur de créer le fichier objet. De même, les fichiers d'en-tête C++ déclarent la promesse de fonctions, de structures, de classes, etc. C'est cette définition que le compilateur utilise pour réserver de l'espace dans la pile, etc.

Les fichiers .c ou .cpp ont l'implémentation. Comme le compilateur convertit chaque fichier d'implémentation en un fichier objet, il existe des crochets pour les concepts non implémentés (ce qui a été déclaré dans l'en-tête). L'éditeur de liens lie les crochets aux implémentations dans d'autres fichiers objets et crée un binaire plus grand qui inclut tout le code (bibliothèque partagée ou exécutable).

VS spécifique

Quant à travailler avec ceux de Visual Studio, il existe des assistants qui facilitent un peu les choses. Le nouvel assistant de classe créera votre paire correspondante d'en-têtes et de fichiers d'implémentation. Il existe même une fonction de navigateur de classe qui vous permettra de déclarer de nouvelles méthodes. Il injectera la définition dans l'en-tête et le talon d'implémentation dans le fichier .cpp. Visual Studio possède ces fonctionnalités depuis plus d'une décennie (depuis que je les utilise).

16
Berin Loritsch

Devenez un développeur Java.

Si vous devez vraiment continuer à développer en C++, vous pouvez essayer d'utiliser un IDE. Souvent, ils offrent un mécanisme par lequel vous pouvez ajouter une méthode à une classe, et il place automatiquement la déclaration dans le fichier .h et la définition dans le fichier .cpp.

13
Paul Butcher

Vous pourriez être intéressé par le programme makeheaders de Hwaci (ceux qui font SQLite et Fossil).

Jetez également un œil à comment Fossil est construit pour avoir une idée.

8
Benoit

Lorsque vous écrivez les premières lignes d'une nouvelle classe, c'est généralement parce que vous en avez besoin au même endroit à ce moment-là. Plus tard, il pourrait être utilisé à plus d'endroits, mais initialement ce n'est généralement pas le cas.

Beaucoup de mes cours commencent en haut du fichier .cpp actuel. Quand il a suffisamment stabilisé pour l'utiliser à plusieurs endroits, je le coupe-collez dans un en-tête. Bien que souvent la classe disparaisse aussi vite qu'elle est apparue.

5
Sjoerd

Le fichier d'en-tête (.h) décrit le interface du code, car c'est le bit niquement que autre code peut voir.

Le fichier source (.cpp) fournit l'implémentation du code que personne d'autre n'a besoin de connaître.

vous incluez un fichier .h qui n'inclut pas .cpp ...

Correct.

En tant que consommateur de ce code, vous n'avez besoin que du fichier d'en-tête pour que le compilateur sache ce qui est disponible dans ce code avec lequel vous pouvez travailler. Le code source C++ n'est utilisé d'aucune façon, forme ou forme à ce stade (ou, au moins, il ne devrait pas être).

... mais les fichiers .cpp sont également compilés.

Oui, mais complètement séparément.

Le fichier .cpp d'un module/bibliothèque que vous utilisez est compilé dans un fichier objet (.o/.dll) par le développeur de cette bibliothèque. Ce fichier objet contiendra des points d'entrée qui ont la même "forme" que ceux décrits dans le fichier d'en-tête.

Vous aurez besoin de ce fichier objet lorsque vous arriverez à link votre exécutable terminé, auquel cas l'éditeur de liens peut saisir le contenu du fichier objet et l'intégrer dans votre exécutable (c'est pour la liaison statique; la liaison dynamique obtient plus compliqué)
Fondamentalement, l'éditeur de liens doit "joindre les points" entre les points d'entrée que votre code attend pour pouvoir appeler, en fonction de ce qu'il a vu dans le fichier d'en-tête et de ce qui se trouve réellement dans la bibliothèque elle-même).

0
Phill W.