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 :

forwarder une declaration


Sujet :

C++

  1. #1
    Membre confirm�
    Inscrit en
    Janvier 2008
    Messages
    74
    D�tails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 74
    Par d�faut forwarder une declaration
    bonjour,

    pourquoi on forward la declaration d'une class

    Merci

  2. #2
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,

    Le compilateur lit le code source un peu � la mani�re dont tu lis ton roman pr�f�r�: de haut en bas.

    Lorsqu'il arrive � la ligne X, il "connait" donc tous les symboles qui ont �t� d�clar�s jusqu'� la ligne X-1, mais il n'a aucune connaissance de ce qui se trouvent... aux lignes suivantes.

    Or, on ne peut utiliser que ce que le compilateur connait d�j�, sous peine d'avoir un message d'erreur proche de "XX ne repr�sente pas un type".

    En effet, lorsque tu souhaite instancier un objet, tu dois veiller � ce que le compilateur ... connaisse le type de l'objet:

    Non seulement, le compilateur doit savoir qu'il existe un type nomm� NomType, par exemple, mais, pour pouvoir instancier un objet, il doit savoir... la taille que cet objet va utiliser en m�moire.

    Evidemment, si tu veux invoquer une fonction membre depuis cet objet, il faudra que le compilateur... sache que cette fonction membre existe...

    Le probl�me vient lorsque l'on doit cr�er deux types particuliers qui... font r�f�rence l'un � l'autre...

    En effet, si tu as une classe (ou une structure) A et une classe (ou une structure) B, que A utilise B et que B utilise A, il y aura, fatalement, une classe qui sera... d�finie avant l'autre...

    Par chance, lorsque le compilateur n'a aucun besoin de connaitre l'espace m�moire utilis� par un type donn� ni les membres et fonctions membres dont il est compos�, il peut se contenter de savoir "qu'il existe" un type portant un nom donn�.

    Il y a deux cas dans lesquels le compilateur peut se contenter de connaitre l'existence d'un type donn�:

    Lorsque l'on utilise un pointeur vers un objet du type indiqu�, parce qu'un pointeur n'est jamais qu'une adresse m�moire � laquelle on trouvera l'objet r�ellement concern� et qu'une adresse m�moire a une taille fixe.

    Lorsque l'on utilise une r�f�rence vers un objet du type indiqu�, parce que, lorsque l'on s'int�resse au code binaire (ou assembleur) g�n�r� par l'utilisation d'une r�f�rence, on se rend compte qu'il est strictement identique... � celui utilis� par les pointeurs.

    Cependant, le seul fait de savoir qu'il existe des types nomm�s, pour reprendre l'exemple ci-dessus, A et B, ne sera suffisant que tant... qu'on essayera pas d'acc�der au contenu d'un objet de type A ou B.

    En effet, si on souhaite acc�der � un membre ou � une fonction membre du type A, le compilateur devra... savoir que le type ou la fonction en question existe, et donc, disposer de la d�finition compl�te de la classe.

    Par contre, s'il s'agit, simplement, de d�clarer, dans A, un membre qui soit un pointeur ou une r�f�rence vers un objet de type B ou une fonction membre prenant en argument un pointeur ou une r�f�rence vers un objet de type A, le seul fait que le compilateur sache qu'il existe "un type nomm� A (ou B)" sera largement suffisant.

    La mani�re de s'y prendre pour indiquer simplement au compilateur"qu'il existe un type nomm� A (ou B)" s'appelle... la d�claration anticip�e (forward declaration).

    Ainsi, nous pouvons envisager d'�crire les fichiers d'en-t�te suivants:
    A.h
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /* directives permettant d'éviter les inclusions multiples */
    #ifndef A_H
    #define A_H
    class B; //déclaration anticipée de B
    class A
    {
        public:
            A();
            ~A();
            void foo(B &); // on n'utilise pas vraiment B ici: on indique "juste"
                           // que foo a besoin d'une référence vers un B
            void doSomething();
        private:
            B * my_b; // la taille d'un pointeur est connue...
                      // typiquement, elle est de 32 ou 64 bits sur PC
    };
    #endif  // fin de la directive contre les inclusions multiples
    B.h
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /* directives permettant d'éviter les inclusions multiples */
    #ifndef B_H
    #define B_H
    class A; //déclaration anticipée de A
    class B
    {
        public:
            void foo(A &); // on n'utilise pas vraiment A ici: on indique "juste"
                           // que foo a besoin d'une référence vers un A
        private:
            A * my_a; // le compilateur se contente de savoir qu'il existe
                      // qu'il existe un type nommé A
    };
    #endif  // fin de la directive contre les inclusions multiples
    Par contre, pour pouvoir manipuler le type A au d�part du type B (ou invers�ment), nous devons veiller � ce que le compilateur... sache de quoi sont compos� aussi bien les A que les B.

    Il faudra donc veiller � inclure les deux fichiers dans t�te dans les fichiers d'impl�mentation:
    A.cpp
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    #include <A.h> // pour disposer de la définition de A
    #include <B.h> // pour disposer de la définition de B
    void A::foo(B& ref)
    {
        ref.foo(*this); //c'est ici que l'on a besoin de la définition de B
    }
    A::A():my_b(new B) // ou ici...
    {
    }
    A::~A()
    {
        delete my_b;
    }
    void A::doSomething()
    {
        /*... n'utilise pas forcement my_b, mais peut le faire ;) */
    }
    B.cpp
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    #include <B.h> // pour disposer de la définition de B
    #include <A.h> // pour disposer de la définition de A
    void B::foo(A& ref)
    {
        ref.doSomething; //c'est ici que l'on a besoin de la définition de A
    }
    Pour conclure, nous pouvons �pingler le fait que, en plus de permettre de r�soudre les probl�mes li�s � ces "d�pendances circulaires", les d�clarations anticip�es permettent de respecter plus facilement la loi demeter.

    Cette loi indique en effet que si une classe A utilise une classe B et que B utilise une classe C, la classe A ne devrait avoir aucune connaissance de la classe C (ou du moins, ne devrait pas pouvoir manipuler un objet de type C).

    Si tu fait une d�claration anticip�e de C dans B.h, et que tu inclues B.h (sans inclure C.h) dans A.h (ou dans A.cpp), toute tentative d'acc�der � un des membres de C au d�part d'une fonction membre de A se soldera... par une erreur de compilation
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  3. #3
    Membre confirm�
    Inscrit en
    Janvier 2008
    Messages
    74
    D�tails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 74
    Par d�faut
    merci beaucoup koala01.

    c'est la meilleur r�ponse que j'ai eu depuis que je me suis inscris au forum .

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. transformer une declaration autrement
    Par hb2012 dans le forum D�buter
    R�ponses: 5
    Dernier message: 30/05/2012, 11h30
  2. Erreur sur une declaration de class avec un extends
    Par kkt8 dans le forum SWT/JFace
    R�ponses: 2
    Dernier message: 18/11/2010, 16h40
  3. Probleme de traduction d'une declaration Delphi
    Par blondelle dans le forum C++Builder
    R�ponses: 7
    Dernier message: 26/10/2008, 20h43
  4. forwarder une erreur d'un servlet vers une error.jsp
    Par jakouz dans le forum Servlets/JSP
    R�ponses: 1
    Dernier message: 14/12/2006, 16h09
  5. R�ponses: 1
    Dernier message: 23/08/2006, 12h01

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