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 :

Visibilité entre instances, les fonctions amies


Sujet :

C++

  1. #21
    Membre du Club Avatar de mouchT8
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 141
    Points : 49
    Points
    49
    Par défaut
    J'utilise Visual Studio 2005

  2. #22
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    Alors je pense que c'est que tu as oublié les gardes d'inclusion pour ton en-tête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #ifndef MACLASS_H
    #define MACLASS_H
    /* ici la déclaration de la classe, etc */
    #endif

  3. #23
    Membre éclairé
    Avatar de buggen25
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    554
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Août 2008
    Messages : 554
    Points : 709
    Points
    709
    Par défaut chez M$
    salut
    Mais des fois VC++ ne fait de difference entre
    et
    en ce qui concerne les include basé dans les repertoires "include". et ce a partir de VC++ 7.

  4. #24
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 631
    Points : 30 707
    Points
    30 707
    Par défaut
    Salut,

    A vrai dire, le problème de l'inclusion en utilisant les chevrons '< >' ou les guillemets ' " " ' tiens principalement à l'ordre dans lequel le préprocesseur va parcourir les répertoires à la recherche du fichier d'en-tête, en s'arrêtant au premier fichier correspondant trouvé.

    Lorsque le nom de fichier est entouré de guillemets, le préprocesseur cherchera en premier dans le répertoire dans lequel se trouve le fichier qui demande l'inclusion, puis dans les répertoires définis (directement par la configuration du compilateur ou à l'aide de l'option -I ) comme contenant des fichiers d'en-tête.

    Si le nom est entouré de chevrons, le préprocesseur cherchera directement dans les répertoires définis (directement par la configuration du compilateur ou à l'aidre de l'option -I )

    Pour répondre à mouchT8, je rejoins l'idée de Alp en ce qui concerne les inclusions.

    en effet, l'inclusion de fichiers se fait de manière récursive, et il y a donc lieu de s'assurer qu'un même fichier qui serait inclus par d'autres ne soit systématiquement recopié afin de respecter la règle de la définition unique.

    Pour te permettre de comprendre, je te propose d'imaginer une arborescence de fichiers qui ressemblerait à
    fichier1.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    /* n'importe quoi */
    fichier2.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "fichier1.h"
    struct Brol
    {
        /*...*/
    };
    fichier3.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #include "fichier1.h"
    /*n'importe quoi */
    fichier4.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "fichier2.h"
    #include "fichier3.h"
    /*voire, pourquoi pas */
    #include "fichier1.h"
    /*n'importe quoi */
    et qui ressemble sans doute très fort à la situation dans laquelle tu te trouve actuellement.

    Le mécanisme d'inclusion va agir exactement comme si tu faisais un copier coller du contenu du fichier inclus à l'emplacement de la directive.

    Cela signifie que, dans fichier2.h et fichier3.h (selon mon exemple), la première ligne sera remplacer par l'ensemble de ce qui se trouve dans fichier1.h

    Jusque là, il n'y a - a priori - aucun problème: ce qui est déclaré / défini dans fichier1.h n'apparait effectivement qu'une fois dans fichier2.h et dans fichier3.h

    Le problème va se poser dans fichier4.h.

    En effet, quand le processeur va parcourir fichier4.h, il va tomber sur l'inclusion de fichier2.h, et, en "brave petit soldat", il va copier coller le contenu de fichier2.h à la place de la directive d'inclusion.

    Mais il ne va pas "sauter" le contenu de fichier2.h, au contraire...

    Il va... traiter le contenu de fichier2.h, et va - fatalement - tomber sur... l'inclusion de fichier1.h...

    En "brave petit soldat", il va donc ... copier coller le contenu de fichier1.h à la place de la directive d'inclusion.

    C'est le fait qu'il traite le contenu qu'il vient de remplacer qui fait qu'il va, en pratique, travailler de manière récursive, et cela peut remonter très loin, la norme garantissant que le préprocesseur doit etre en mesure de traiter de manière récursive... niveaux 256 d'inclusion.

    Mais, après avoir traité fichier2.h, il ne va pas s'arrêter là.

    Il va continuer à traiter fichier4.h et va rencontrer... la directive d'inclusion de fichier3.h.

    Encore une fois, en brave petit soldat, il va donc effectuer un copier coller du contenu de fichier3.h, et va... le traiter.

    Et comme dans fichier3.h, il y a aussi une directive d'inclusion de fichier1.h, il va à nouveau... copier coller le contenu de fichier1.h à la place de la directive d'inclusion, et il va à nouveau traiter le contenu du fichier.

    Une fois qu'il aura fini de traiter fichier3.h, il reprendra le traitement de fichier4.h là où il l'a laissé, et ainsi de suite.

    Le problème est donc que, dans le seul fichier4.h, tu va trouver
    1. le contenu de fichier1.h inclus récursivement du fait de l'inclusion de fichier2.h
    2. le contenu de fichier1.h inclus récursivement du fait de l'inclusion de fichier3.h
    3. le contenu de fichier1.h inclus du fait de l'inclusion de... fichier1.h

    tu va donc te retrouver avec... trois définitions de choses identiques à trois places différentes, ce qui, fatalement, ne respecte absolument pas la règle de la définition unique

    Pour pallier à ce problème, l'idée est donc de demander au préprocesseur de ne garder les définitions qui se trouvent dans un fichier que si elles n'ont pas encore été rencontrées pendant le traitement qui précède.

    Pour y arriver, nous allons décider chaque fois d'un identifiant que nous veillerons à garder unique.

    Il existe plusieurs possibilités, mais l'une de celles qui sont couramment utilisées est d'utiliser le nom du fichier (extension comprise) en majuscule, et en prenant soin de remplacer tous les caractères non alpha-numérique par un underscore

    Au final, fichier1.h pourrait devenir quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* si le symbole FICHIER1_H n'a pas encore été défini */
    #ifndef FICHIER1_H 
    /* nous définissons le symbole FICHIER1_H */
    #define FICHIER1_H
    /* toutes les définitions de fichier1.h */
    #endif // fin du #ifndef FICHIER1_H
    Evidemment, fichier2.h, fichier3.h et fichier4.h seront modifiés exactement de la même manière, en utilisant respectivement FICHIER2_H, FICHIER3_H et FICHIER4_H
    De cette manière, le comportement du préprocesseur va changer:

    Lorsqu'il traitera fichier4.h, il va rencontrer le test "FICHIER4_H est il défini " auquel il répondra bien sur par non (il ne connait pas ce symbole)
    il va donc "garder le contenu" du fichier, et le parcourir.

    à la ligne suivante (commentaires non compris), il va rencontrer la directive qui lui demande... de définir le symbole FICHIER4_H, et il va le faire
    il va ensuite rencontrer la directive d'inclusion de fichier2.h, et va agir de manière normale en effectuant un copier coller du contenu de fichier2.h à la place de la directive d'inclusion.

    Et bien sur, il va traiter le contenu, dans lequel il rencontrera le test "FICHIER2_H est il défini ", et auquel il répondra de nouveau par "non".

    Il va donc garder ce qui suit, déclarer le symbol "FICHIER2_H" comme ça lui est demandé, et... effectuer un copier coller du contenu de... fichier1.h, comme cela lui est demandé.

    Contenu qu'il va traiter, en commençant par répondre à la question "FICHIER1_H est il défini ", toujours par la même réponse : "non, je ne le connais pas"

    Il va donc (parce que c'est ce qu'on lui demande) définir le symbole "FICHIER1_H" et garder le contenu.

    Une fois qu'il aura fini de traiter fichier1.h, il reprendra le traitement de fichier2.h là où il l'avait laissé, et, une fois qu'il aura fini de traiter fichier2.h, il reprendra le traitement de fichier4.h là où il l'avait laissé.

    Il rencontrera donc la directive d'inclusion de fichier3.h, et, comme d'habitude, il effectuera un copier coller du contenu de fichier3.h à la place de la directive d'inclusion.

    Comme il ne connais pas le symbole FICHIER3_H, il agira pour fichier3.h comme il l'a fait pour fichier2.h...

    Là où ca change, c'est que, quand il va devoir traiter l'inclusion de fichier1.h dans fichier3.h, le symbole "FICHIER1_H" sera connu...

    Il va donc supprimer tout ce qui se trouve à l'intérieur du test (donc: tout ce qui se trouve entre #ifndef FICHIER1_H et le #endif correspondant)

    Après avoir traité fichier3.h, il continuera le traitement de fichier4.h, et, là encore, il effectuera un copier coller du contenu de fichier1.h à la place de la directive d'inclusion, mais, là encore, le symbole "FICHIER1_H" sera connu, et donc, le contenu à l'intérieur du test sera supprimé.

    Au final, nous aurons donc la certitude que tout ce qui est défini dans un fichier d'en-tête ne sera effectivement défini qu'une et une seule fois

  5. #25
    Membre du Club Avatar de mouchT8
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 141
    Points : 49
    Points
    49
    Par défaut
    wAHOU merci à vous pour toutes ces aides !
    Je comprend pas pourquoi je n'ai pas eut une seule ligne à ce propos dans mes cours ...
    Enfin bref , il ne vaut mieux pas encore polémiquer sur la qualité des cours de Educatel....!

    Je vais pouvoir modifier tout ça maintenant, c'est vrai que c'est plus pratique de mettre les classes ainsi dans des fichiers différents, maintenant que je le fait, je comprend pourquoi c'est plus facile à comprendre

    Merci à tous !

Discussions similaires

  1. Decalage, Probleme d'ordre d'entrée dans les fonctions
    Par clouddd dans le forum Débuter
    Réponses: 2
    Dernier message: 25/04/2010, 23h15
  2. Les fonctions amies.
    Par white_fire dans le forum Qt
    Réponses: 3
    Dernier message: 01/04/2009, 22h00
  3. Réponses: 2
    Dernier message: 25/10/2007, 14h56
  4. Comparaison entre les classes et les fonctions
    Par Ashgenesis dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 08/09/2005, 20h09

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