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 :

Règle d'insertion de la directive include


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut Règle d'insertion de la directive include
    Bonjour à tous.

    Je n'arrive pas à trouver une réponse pour cette question : Existe-t-il une règle pour placer les directives #include <> ou #include" ".

    Faut-il les mettre dans l'entête plutôt que dans le source ?

    Faut-il les mettre là où la fonction est appelée ?

    Cette dernière solution me semblerait logique, sauf si le compilateur en a besoin avant.

    J'ai fait de simple test, mais dans les deux cas ça fonctionnait. Bref vous comprenez que je suis un peu hésitant.

    Merci pour votre point de vue.

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 748
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 748
    Par défaut
    C'est plus difficile que cela et on peut avoir des problèmes (des "choses" non déclarées ou déclarées plusieurs fois)

    Parce que, lorsque tu inclus une entêtre, tu inclus en même temps les entêtes qui sont dans l'entête.

    Tu as donc un arbre d'inclusion , et il faut faire attention à ce que dans cet arbre tu n'es qu'une seule fois une entête [dans un sous arbre]

    Après si tu appelles plusieurs fois une entête, tu as les include guards qui protègent.

    Et enfin, j'évite de mettre trop d'include dans les entêtes et je fais des "forward declaration" (déclaration anticipée *) à la place, si c'est possible.


    * -> Merci Médinoc

  3. #3
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 435
    Par défaut
    Tu peux faire ce que tu veux, l'include, c'est juste mettre le contenu d'un fichier dans un autre.
    Le pré-processeur fera ce que tu demandes.

    MAIS, faut pas faire nimportenawak juste parce que personne ne te l'interdit.

    Il faut rendre ton code maintenable.

    Et le plus simple, et de loin, pour qu'il reste maintenable, c'est de mettre les includes au début du fichier.

    L'ordre des includes est aussi très important.

    On commence par les includes des librairies "globales" comme celles des librairies graphiques, des librairies d'accès aux données, etc..., pour savoir rapidement à quelle partie/module de l'application le code lié.
    (On utilise des <> pour ce type d'include)

    On suit par les includes des classes du projet/module du projet qui doivent être connues par le code de fichier, pour savoir les interdépendances entre ce fichier et les autres éléments du même module.
    (On utilise des "..." pour ce type d'include)

    On finit avec les includes "domestiques" comme "algorithm", vector, stream, etc de la STL qui n'indique rien sur le placement/dépendance logique du code dans le projet.
    (On utilise des <> pour ce type d'include)

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    Par défaut
    Alors, hormis pour la programmation Win32 qui est un peu spéciale de ce côté-là, la règle de base c'est que chaque fichier d'en-tête doit être auto-suffisant, donc il doit inclure tous ceux dont il dépend.

    C'est-à-dire, tout ceux dont il utilise des types, ou tout ce qui est utilisé par le code de fonctions inline, etc. (sauf dans le cas où une déclaration anticipée suffit).

    Prenons un exemple:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //Toto.hpp
    #pragma once
     
    #include "Tata.hpp" //Inclusion
    class Titi; //Déclaration anticipée
     
    //Cette déclaration utilise le type Tata, et vu que c'est par valeur, on ne peut pas utiliser une déclaration anticipée
    void UneFonction(Tata monObjet);
     
    //Ici le type Titi est pris par référence, et une déclaration anticipée suffit
    void UneAutreFonction(Titi& monObjet);

    Il peut alors être directement utilisé dans un code qui en a besoin, sans avoir à inclure un autre fichier d'en-tête avant.
    Note par contre, que le code appelant aura quand même besoin d'un #include "Titi.hpp" pour appeler UneAutreFonction().
    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.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut
    Merci à tous pour vos réponses.

    Je ne m'attendais pas à des réponses aussi "arborescentes" (cf l'arbre d'inclusion).

    - Pour les déclarations anticipées, je n'ai pas encore vue cela, je vais devoir étudier ce point.
    - Pour les include guards, pas de problème j'ai compris et j'en mets dans mes fichiers. Peut-on malgré cela se retrouver avec une inclusion multiple ?



    L'ordre des includes est aussi très important.
    Donc en prenant un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #include <QtCharts>
    #include "maClasse.h"
    #include <iostream>
    Et le plus simple, et de loin, pour qu'il reste maintenable, c'est de mettre les includes au début du fichier.
    Du fichier d'en-tête je suppose.

    Mais prenons un cas pratique qui est à l'origine de cette question. J'utilise une fonction, par exemple std::cout de la bibliothèque <iostream> dans mon code source. C'est une fonction interne au fichier .cpp et aucun prototype de méthode n'a besoin de cette fonction. Je mets quand même la directive #include <iostream> dans mon fichier d'en-tête, pas dans le .cpp ?
    De ce fait, dans mes fichiers .cpp je n'ai que les #include "fichier.h" ?


    Merci pour cette précision complémentaire.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 145
    Billets dans le blog
    4
    Par défaut
    L'include ne fait que remplacer la ligne par le contenu du fichier.
    Si cout n'est pas utilisé dans le header, pourquoi l'inclure dans le header ?
    Plus le header est léger, plus la compilation est rapide.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut
    Merci Bousk.

    Ca répond à mon problème et surtout, ça valide mon raisonnement.

  8. #8
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 435
    Par défaut
    Du fichier d'en-tête je suppose.
    Le raisonnement est le même pour les fichiers .h et .cpp.

    Il ne devrait pas avoir d'include "domestiques" dans le .h car cela ne sert que pour l'implémentation des fonctionnalités, donc rien à faire dans le .h.
    Si c'est pour des fonctions inline, c'est qu'elles sont vraisemblablement trop complexes pour être efficacement inline.

    Pour reprendre la réponse de @Bousk, on n'inclus que ce qui est nécessaire au fichier, le .h ou le .cpp, donc pas d'include de trucs nécessaire au .cpp dans le .h. C'est au .cpp de se démerder seuls.

    Privilégiés les déclarations anticipées et le fait de rendre votre code le plus réutilisable donc réduire le plus possible les includes de .h => moins de dépendance => code plus souple à la réutilisation.

  9. #9
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 748
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 748
    Par défaut
    Citation Envoyé par KonTiKI Voir le message
    Peut-on malgré cela se retrouver avec une inclusion multiple ?
    C'est l'étape d'après , les unités de compilation et le mot clef extern/ static (<- mais en partie)

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Par défaut
    Sujet particulièrement intéressant avec, comme d'habitude, des réponses d'un haut niveau. Débutant s'accrocher.

    Encore une journée de progrès aujourd'hui, merci à tous.

    PS : pour l'étape d'après, je vais attendre d'avoir ingurgité celle là, car il m'en reste à avaler.


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Modification des règles d'insert sur les vues
    Par LeFredBleu dans le forum Requêtes
    Réponses: 0
    Dernier message: 18/05/2010, 23h41
  2. Probleme de quote dans la directive include
    Par hlavigne dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 20/12/2009, 01h51
  3. Objet jsp directive.include
    Par Rifer dans le forum JSF
    Réponses: 2
    Dernier message: 19/02/2009, 15h03
  4. [jsp]directive include
    Par noOneIsInnocent dans le forum Servlets/JSP
    Réponses: 17
    Dernier message: 20/09/2005, 17h52
  5. [ JSP ] directive include file
    Par goolix dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 05/08/2004, 16h53

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