J'ai un devoir et j'ai besoin d'évaluer quelle approche est la meilleure selon GRASP "Variation Protégée". J'ai trouvé une question sur Stack Overflow sur la séparation des fichiers d'en-tête et de code en C ++ .
Cependant, ce que je veux savoir pourquoi Java ne suit pas C ++ pour promouvoir la séparation entre les définitions de classe et les implémentations de classe. Y a-t-il des avantages avec la méthode Java par rapport à la méthode C ++?
java
programming-languages
c++
Etienne Noël
la source
la source
private
, afin que l'implémentation connaisse la taille et lesprivate
fonctions de membre également.Réponses:
Combien de lignes de code sont dans le programme suivant?
Vous avez probablement répondu 7 (ou 6 si vous n'avez pas compté la ligne vierge, ou 4 si vous n'avez pas compté les accolades).
Votre compilateur voit cependant quelque chose de très différent:
Oui, c'est 18,7 KLOC juste pour un "Bonjour, monde!" programme. Le compilateur C ++ doit analyser tout cela. C'est une des principales raisons pour lesquelles la compilation C ++ prend si longtemps par rapport aux autres langages, et pourquoi les langages modernes évitent les fichiers d'en-tête.
Une meilleure question serait
Pourquoi ne C ++ ont des fichiers en- tête?
C ++ a été conçu pour être un surensemble de C, il devait donc conserver les fichiers d'en-tête pour une compatibilité descendante.
OK, alors pourquoi C a-t-il des fichiers d'en-tête?
En raison de son modèle de compilation séparé primitif. Les fichiers objets générés par les compilateurs C n'incluent aucune information de type, donc pour éviter les erreurs de type, vous devez inclure ces informations dans votre code source.
L'ajout des déclarations de type appropriées corrige le bogue:
Notez qu'il n'y a pas de par
#include
. Mais lorsque vous utilisez un grand nombre de fonctions externes (ce que la plupart des programmes utiliseront), leur déclaration manuelle devient fastidieuse et sujette aux erreurs. Il est beaucoup plus facile d'utiliser des fichiers d'en-tête.Comment les langues modernes peuvent-elles éviter les fichiers d'en-tête?
En utilisant un format de fichier objet différent qui inclut des informations de type. Par exemple, le format de fichier Java * .class comprend des "descripteurs" qui spécifient les types de champs et les paramètres de méthode.
Ce n'était pas une nouvelle invention. Plus tôt (1987), lorsque Borland a ajouté des «unités» compilées séparément à Turbo Pascal 4.0, il a choisi d'utiliser un nouveau
*.TPU
format plutôt que Turbo C*.OBJ
afin de supprimer le besoin de fichiers d'en-tête.la source
OBJ
fichiers plutôt queTPU
s ...Java a des interfaces pour définir un contrat. Cela donne un niveau d'abstraction plus élevé par rapport aux besoins de l'appelant et à la mise en œuvre réelle. c'est-à-dire que l'appelant n'a pas besoin de connaître la classe d'implémentation, il a seulement besoin de connaître le contrat qu'il prend en charge.
Disons que vous voulez écrire une méthode qui ralentit toutes les clés / valeurs dans une carte.
Cette méthode peut appeler entrySet () sur une interface abstraite qui est supprimée de la classe qui l'implémente. Vous pouvez appeler cette méthode avec.
la source
#define interface class
.virtual
mot - clé pour obtenir le polymorphisme et cela n'a aucune incidence sur les performances si vous n'utilisez qu'un ou deux types concrets, comme ils le sont en Java. Pouvez-vous m'indiquer une documentation sur la façon dont cela fonctionne en C ++?Franchement, les en-têtes existent comme un accident historique. C'est un système incroyablement pauvre, aucune autre langue n'a quelque chose d'aussi terrible, et quiconque n'a pas à s'en occuper devrait s'en réjouir.
la source
Les en-têtes sont là pour permettre une compilation séparée. En #incluant les en-têtes, le compilateur n'a besoin de rien savoir de la structure binaire du code C ++ compilé et peut laisser ce travail à un éditeur de liens séparé. Java n'utilise pas un éditeur de liens séparé avec son compilateur, et puisque les fichiers .class sont strictement définis, le compilateur est capable de les lire pour déterminer tous leurs membres avec tous leurs types, sans avoir besoin de les déclarer à nouveau dans chaque unité de compilation.
Vous pouvez inclure toute l'implémentation dans un en-tête C ++, mais cela oblige le compilateur à le recompiler chaque fois qu'il est #inclu, forçant l'éditeur de liens à trier et à supprimer les copies en double.
la source
Java favorise la séparation de la définition et de l'implémentation des classes, cela dépend juste d'où vous cherchez.
Lorsque vous êtes l'auteur d'une classe Java, vous pouvez voir la définition de la classe ainsi que son implémentation dans un seul fichier. Cela simplifie le processus de développement car vous n'avez qu'à aller à un seul endroit pour maintenir la classe, vous n'avez pas à basculer entre deux fichiers (.h et .cpp comme vous le feriez en C ++). Cependant, lorsque vous êtes le consommateur de la classe, vous ne traitez que la définition, via un fichier .class qui est soit conditionné dans un .jar soit dans un .class autonome
C ++ vous permet de séparer la définition et l'implémentation, mais c'est ad hoc. Par exemple, rien ne vous empêche d'écrire la méthode en ligne dans le fichier d'en-tête, et pour les classes de modèle, cela est obligatoire. Le fichier d'en-tête répertorie également toutes les variables membres, qui sont visibles par toute personne qui regarde le fichier d'en-tête, même si elles sont un détail d'implémentation de la classe et non pertinentes pour un consommateur.
la source