IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

intérêt des fichiers headers


Sujet :

C++

  1. #1
    Nee
    Nee est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 50
    Par défaut intérêt des fichiers headers
    Bonjour a tous,

    Développeur PHP, je poursuis lentement mais surement ma petite exploration du monde merveilleux du C++.

    Après avoir crée des classes et implémenté leurs méthodes dans des fichiers .cpp, je me pose des questions sur l'inclusion de ces classes :
    - Pourquoi je n'inclurai pas directement les fichiers .cpp dans mon main ?
    - Les .h ne servent qu'a définir les méthodes publiques pour une classe. Pourquoi ce fichier n'est pas généré automatiquement par le compilateur ?

    Merci de m'éclairer !

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par Nee Voir le message
    - Pourquoi je n'inclurai pas directement les fichiers .cpp dans mon main ?
    Parce que non seulement c'est sale, mais si tu modifies un truc dans un .cpp, même un simple commentaire, tu te retrouves obligé de tout recompiler.
    - Les .h ne servent qu'a définir les méthodes publiques pour une classe. Pourquoi ce fichier n'est pas généré automatiquement par le compilateur ?
    Parce qu'ils déclarent les méthodes privées aussi, ainsi que les variables membres. Et ils disent quelles méthodes sont privées ou publiques.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Parce qu'ils déclarent les méthodes privées aussi, ainsi que les variables membres. Et ils disent quelles méthodes sont privées ou publiques.
    + les méthodes inline, virtual, friend, ....

  4. #4
    Nee
    Nee est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 50
    Par défaut
    bonjour,

    Je comprends bien l'interet de la compilation séparée.

    Beaucoup d'aspect du language m'échappe, mais je ne peux pas m'empecher d'avoir l'impression de "perdre du temps" a réécrire le prototype de chacune de mes méthodes dans un fichier séparé.

  5. #5
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Exemple:
    Si tu fais une librairie en C++ et que tu la livres à quelqu'un pour qu'il l'utilise, tu vas fournir la librairie statique (.LIB) ou la librairie dynamique (.DLL), mais surtout le fichier .H qui donne l'interface de ta librairie. Tu n'es pas obligé de fournir les sources complètes (les implémentations des fonctions de ta librairie) si ce n'est pas nécessaire ou si tu veux rester maître de ta librairie.

  6. #6
    Nee
    Nee est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 50
    Par défaut
    Oui, je comprends le but, mais c'est le coté "doublon" de l'écriture du prototype qui me chagrinne.
    Au moment du dev, il m'arrive de changer des noms de méthode, il faut le changer a deux endroits.

    En fait, c'est comme si j'écrivais manuellement la table des matiere d'un document...

    Mais si c'est une contrainte du langage, je vais devoir m'y plier

  7. #7
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Dans la déclaration (h), tu vas pouvoir mettre des paramètres par défaut pour des arguments de fonction, pas dans l'implémentation (cpp).
    Code header : Sélectionner tout - Visualiser dans une fenêtre à part
    int MyFonction(int iParam1, int iParam2 = 5, int iParam3 = 10);
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int iRetour = MyFonction(2);
     
     
     
    int MyFonction(int iParam1, int iParam2, int iParam3)
    {
        // traitement
        ....
     
        return ....;
    }
    Le premier paramètre doit être spécifié alors que le 2e et le 3e sont optionnels.

  8. #8
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    Dans le .h tu peux mettre la déclaration de ta fonction, et dans le .cpp sa définition. De cette manière, tu as juste à inclure le .h dans les .cpp qui ont besoin de connaître la classe, sans te poser mille questions. Avec les gardes d'inclusion, tu es sûr qu'aucune classe ne sera déclarée et définie de façon redondante, provoquant des erreurs.

    PS:
    Citation Envoyé par Nee Voir le message
    monde merveilleux du C++
    Je ne sais pas si les modo sont sensibles à la flatterie, ça peut être risqué des fois

  9. #9
    Nee
    Nee est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 50
    Par défaut
    Merci pour vos réponses, mais je reste surpris du fait que personne ne s'étonne d'être obligé d'avoir du code dupliqué (prototypes).

    Visiblement il existe des scripts qui génére le header a partir d'une declaration de classe, mais je ne sais pas si il est efficace a l'utilisation
    http://www.lazycplusplus.com

  10. #10
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Citation Envoyé par Nee Voir le message
    Merci pour vos réponses, mais je reste surpris du fait que personne ne s'étonne d'être obligé d'avoir du code dupliqué (prototypes).
    Et je persiste à dire que c'est parce que de n'est pas la même chose .
    Mais tu auras le temps de t'en rendre compte par toi même au fur et à mesure de tes développements .
    Bon courage!

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Nee Voir le message
    Oui, je comprends le but, mais c'est le coté "doublon" de l'écriture du prototype qui me chagrinne.
    En fait, en C++, tu ne peux connaître le prototype à partir de la définition: par exemple, dans la définition, tu ne sais pas si ta méthode est public/protected/private, tu ne connais pas les valeurs par défaut des paramètres, tu ne sais pas si elle est virtuelle ou statique, etc... Donc la déclaration est là pour 'décrire' la classe: elle dit aux utilisateurs comment ils peuvent l'utiliser, et la définition c'est la cuisine interne. Alors ça peut paraître fastidieux, mais:
    1. Maintenant, les éditeurs sont assez bien équipés pour faciliter ce genre de changement dans de petits projets.
    2. Sinon, l'utilisation d'un modéliseur UML (par expl BOUML) qui génère le code (au moins les définnitions et déclarations) peut t'éviter ces doublons

  12. #12
    Nee
    Nee est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 50
    Par défaut
    Citation Envoyé par spoutspout Voir le message
    Mais tu auras le temps de t'en rendre compte par toi même au fur et à mesure de tes développements .
    Bon courage!
    Oui, j'ai encore du boulo !

    Citation Envoyé par 3DArchi
    Maintenant, les éditeurs sont assez bien équipés pour faciliter ce genre de changement dans de petits projets.
    J'en suis encore à travailler avec un simple editeur de texte (pas IDE) + compilation en ligne de commande, pour pouvoir bien profiter de chaque probleme que je rencontre

  13. #13
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Nee Voir le message
    Visiblement il existe des scripts qui génére le header a partir d'une declaration de classe, mais je ne sais pas si il est efficace a l'utilisation
    http://www.lazycplusplus.com
    J'ai pour ma part tendance à écrire le .h d'abord, voir tous les .h reliés, et seulement après à éventuellement écrire le .cpp (je peux d'ailleurs très bien imaginer dans une grosse organisation que l'écriture d'un .h soit réservé à l'expert, celle du .cpp au petit nouveau).

    Alors, un script qui génère un squelette de .cpp à partir du .h, pourquoi pas, mais dans l'autre sens, ça n'a pour moi aucun intérêt.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  14. #14
    Nee
    Nee est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 50
    Par défaut
    Effectivement. Je laisse de côté pour l'instant les scripts de génération auto.

    Citation Envoyé par 3DArchi Voir le message
    Donc la déclaration est là pour 'décrire' la classe: elle dit aux utilisateurs comment ils peuvent l'utiliser, et la définition c'est la cuisine interne.
    Je réouvre le sujet car le fichier header ne contient pas que l'interface de la classe mais bel et bien une partie du code de l'implémentation : mes variables privées par exemple, que j'utilise dans mes méthodes, les utilisateurs de ma classe n'en ont pas besoin...

  15. #15
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Effectivement, c'est un reproche fait au C++ de devoir décrire (pour des raisons techniques, il faut en dire assez au compilateur pour qu'il fasse correctement la compilation séparée) dans ce qui devrait être l'interface d'une classe des détails d'implémentation.

    Certains utilisent la technique du pimpl pour corriger ce problème, mais c'est assez lourd et ne se justifie qu'au niveau de l'interface d'une bibliothèque.

    D'autres utilisent la notion d'interface à la Java pour le même but (et avec des lourdeurs semblables).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  16. #16
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Après si c'est vraiment écrire deux fois quasiment la même chose utilise un IDE qui te permet de rajouter des méthodes au travers d'une boite de dialogue (VS le fait par exemple - clique droit sur une class dans ClassView puis Add Function). il te créera la déclaration et la définition.

    Mais je ne pense pas que beaucoup de développeur utilise ce wizard pour créer des méthodes. ça fait quand même très (passez moi l'expression) "newbie"

  17. #17
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 474
    Par défaut
    Citation Envoyé par Nee Voir le message
    Je réouvre le sujet car le fichier header ne contient pas que l'interface de la classe mais bel et bien une partie du code de l'implémentation : mes variables privées par exemple, que j'utilise dans mes méthodes, les utilisateurs de ma classe n'en ont pas besoin...
    C'est une question de point de vue : les utilisateurs de ta classe font plus qu'invoquer ses méthodes et utiliser un « service », ils instancient également ton objet au sein de leur propre environnement, et ce, à la compilation. À ce titre, ils peuvent avoir besoin de connaître la taille des instances de tes classes, par exemple.

    Pour les templates, en revanche, tu es obligé de passer le code. Pour protéger la propriété intellectuelle, le mot-clé export a été défini, mais comme c'est très compliqué de l'implémenter (en gros, il faudrait définir une forme officielle de code obscurci, ou bien utiliser les DRM) et que, parallèlement, ce n'est absolument pas une réponse à un problème technique relatif à la compilation, très peu de compilos l'implémentent encore aujourd'hui. Wikipédia affirme qu'il a même été envisagé de retirer le mot-clé du standard C++ ...

  18. #18
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Il a effectivement été proposé d'enlever export, mais cette proposition a été vigoureusement rejetée. Et même l'équipe qui avait proposé ça semble désormais réfléchir à le fournir.

    Par contre, export n'a pas vocation à protéger la propriété intellectuelle, et ne le permet d'ailleurs pas.

    Voir par exemple l'article de Jean-Marc sur ce sujet : http://www.bourguet.org/cpp/export.pdf
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  19. #19
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 474
    Par défaut
    Citation Envoyé par Nee Voir le message
    - Pourquoi je n'inclurai pas directement les fichiers .cpp dans mon main ?
    En théorie, tu peux, mais c'est vraiment très sale.

    L'idée, lorsque tu découpes ton travail en plusieurs fichiers, c'est notamment d'éviter d'avoir à tout recompiler. Donc, tout comme en C, tu compiles une fois, et tu ne recompiles ensuite que ce qui a besoin de l'être. Ensuite, une fois que tous les objets binaires ont été produits séparément, tu fais une édition des liens entre eux.

    D'où l'intérêt (entre autres) des .h, qui contiennent (entre autres) les prototypes de tes classes. Si le code objet a changé mais que la manière de les appeler reste la même, pas besoin de modifier tout le reste.

    Ensuite, tu viens du PHP et il y a une différence majeure : C++ peut compiler le code. Lorsque tu livres une bibliothèque, par exemple, l'utilisateur ne voit plus du tout le code source. Les prototypes de classes et de fonctions sont alors le seul moyen de pouvoir exploiter le code compilé.

    - Les .h ne servent qu'a définir les méthodes publiques pour une classe. Pourquoi ce fichier n'est pas généré automatiquement par le compilateur
    Pour deux raisons :

    D'une part, le compilateur n'a absolument pas à toucher au code source. Il doit l'interpréter et produire un objet à partir de lui. Un générateur de code, en revanche, est un logiciel complètement différent et distinct. C'est le piège des IDE, ça, d'ailleurs, de faire l'amalgamme Que se passerait-il si tu changeais de compilo et/ou de plate-forme ?

    D'autre part, et contrairement à une idée répandue, tu n'es absolument pas tenu d'écrire un .h à chaque fois que tu crées une classe. Pour aller plus loin, le compilateur lui-même se s'appuie pas du tout sur les extensions des fichiers pour en déduire la nature de ce qu'il lit. La seule chose qui compte est le flux continu de code, fût-il obtenu au travers d'inclusions répétées. Il y a juste des règles de bon usage à respecter quand on fait un projet.

    Maintenant, à quoi sert un prototype ? À déclarer à l'avance une entité (fonction, classe) pour pouvoir y faire référence même si elle n'est pas encore définie. Il faut savoir qu'en principe un code source C/C++ est lu en une seule passe (en tout cas par type d'opération). C'était spécialement vrai sur les ordinateurs de 1972, quand le C est sorti. Mais si tu as défini toute ta classe ou ta fonction en amont du code source qui l'utilise, tu n'as pas besoin du prototype.

    Exemple simple avec un seul fichier :

    1) Tu crées un fichier .cpp. Il contient main() et d'autres choses.
    2) Tu comptes définir des fonctions annexes (même pas des classes, à ce stade), et pour que ce soit plus propre, tu aimerais garder l'ordre rédactionnel, et la fonction main() en tête de fichier.
    3) Tu déclares donc toutes tes fonctions tout en haut de ton listing, et tant qu'à faire, tu ajoutes main() dans le lot. C'est facultatif puisqu'elle va être la première à être définie, mais c'est plus propre et ça te permet de garder un résumé de tout ce qui a été écrit dans ton fichier.
    4) Ce bloc de déclaration commence à être imposant. Tu le déportes donc dans un fichier .h et tu le remplaces par un #INCLUDE de ce fichier.
    5) Tu te rends compte que les autres morceaux de ton projet ont besoin de savoir également comment fonctionnent tes classes et fonctions, d'autant que, eux, ils ne liront pas le code.
    6) Tu t'aperçois qu'il te suffit de faire exactement le même #INCLUDE dans les fichiers concernés.

Discussions similaires

  1. Compiler aussi quand un des fichiers header a changé
    Par ikeas dans le forum Eclipse C & C++
    Réponses: 0
    Dernier message: 04/12/2014, 14h27
  2. [C++] Outils pour parser des fichiers header?
    Par Invité dans le forum Autres éditeurs
    Réponses: 0
    Dernier message: 26/04/2013, 16h37
  3. Modifier header des fichiers perl génerés
    Par imikado dans le forum Développement de jobs
    Réponses: 3
    Dernier message: 12/02/2009, 21h41
  4. [gcc] ajouter un chemin relatif a des fichiers header
    Par wodel dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 12/11/2007, 13h54
  5. Réponses: 9
    Dernier message: 25/09/2005, 16h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo