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 :

Séparer prototypes et définitions


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Séparer prototypes et définitions
    Bonjour,

    J'aimerais savoir s'il est possible de séparer prototypes (.hpp) et définitions (.cpp) des méthodes inline; templates; et virtuel d'une classe A.

    Certains disent que c'est possible, d'autre le déconseillent fortement. Qu'en pensez vous ? Merci d'avance pour vos réponse.

  2. #2
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    la plupart des compilateurs ne le gèrent pas. de toutes façon, les fichier .cpp servent surtout pour moi à être compilé indépendamment, ce qui n'est évidemment pas possible pour un template ou une fonction inline.

    Bref. Le plus simple est pour moi, c'est de mettre tes définitions dans un autre .hpp que tu include dans le .hpp de ta classe principale si tu veux les séparer...

    Bonne chance

  3. #3
    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,

    C'est possible pour les fonction inlines et pour les fonctions de classes template, mais sous certaines conditions

    C'est très fortement recommandé pour les fonctions virtuelles.

    Les conditions auxquelles il est possible de définir les fonctions inline et les fonctions de classes template sont identiques (parce qu'elle suivent un raisonnement sensiblement): le code d'implémentation doit être disponible pour chaque appel de la fonction.

    En effet:
    Pour implémenter l'appel d'une fonction inline, le compilateur doit... disposer du code de la dite fonction afin de remplacer l'appel.

    En ce qui concerne les fonctions de classes template, le compilateur ne peut pas créer le code exécutable correspondant tant qu'il n'a pas connaissance de la taille... de tous les types utilisés pour paramétrer les fonctions, chose qu'il ne peut avoir que... quand on crée effectivement une instance particulière (dans le sens de "paramétrée avec un ou des types particuliers) de la classe.

    Note que, quoi qu'il en soit, tu devra expliciter le fait que les fonctions sont inlines, si tu le fais de cette manière

    Enfin, en ce qui concerne les fonctions virtuelles, le propre de ces fonctions est de passer par la vtable de la classe parent, et elles ne peuvent donc pas être inline.

    De plus, si tu place leur définition ailleurs que dans un fichier d'implémentation séparé, tu auras beau les entourer de tous les gardes anti inclusion multiple que tu voudra, tu arrivera au mieux à éviter qu'elles soient définies deux fois dans la même unité de compilation, mais tu aura le plus grand mal à éviter qu'elles ne soient définie dans plusieurs unités de compilation (même si ce n'est qu'une seule fois par unité de compilation).

    Quoi qu'il en soit, la règle de la définition unique sera bafouée, et l'éditeur de liens ne sera plus en mesure de faire son travail correctement
    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

  4. #4
    Invité
    Invité(e)
    Par défaut
    Merci pour vos réponse,

    Mais si j'ai dans un même fichier (A.hpp) les prototypes et définitions (toujours séparé) d'une même classe A :

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    #ifndef FILE__A
    #define FILE__A
     
    class A
    {
    	public:
    		A();
    		bool uu()
    		inline int tt();
    		template<typename T> T ch(T h = 0);
     
    	protected:
    		bool u;
    		int t;
    		int c;
     
    };
     
    A::A() : u(true), t(8), c(1)
    {
     
    }
     
    bool A::uu()
    {
    	return u;
    }
     
    inline int A::tt()
    {
    	return t;
    }
     
    template<typename T> T A::ch(T h)
    {
    	if(h == 1) return h + c;
    }
     
    #endif //FILE__A
    Et que j'ai deux fichiers sources (.cpp) qui incluent ce même fichier. Il ne risquent pas d'avoir un problème de linker ? Comment faire dans ce cas "particulier" ?

    Merci encore

  5. #5
    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
    Citation Envoyé par Abdelite Voir le message
    Merci pour vos réponse,

    Mais si j'ai dans un même fichier (A.hpp) les prototypes et définitions (toujours séparé) d'une même classe A :

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    #ifndef FILE__A
    #define FILE__A
     
    class A
    {
    	public:
    		A();
    		bool uu()
    		inline int tt();
    		template<typename T> T ch(T h = 0);
     
    	protected:
    		bool u;
    		int t;
    		int c;
     
    };
     
    A::A() : u(true), t(8), c(1)
    {
     
    }
     
    bool A::uu()
    {
    	return u;
    }
     
    inline int A::tt()
    {
    	return t;
    }
     
    template<typename T> T A::ch(T h)
    {
    	if(h == 1) return h + c;
    }
     
    #endif //FILE__A
    Et que j'ai deux fichiers sources (.cpp) qui incluent ce même fichier. Il ne risquent pas d'avoir un problème de linker ?
    Non, il n'y a aucun risque...

    Pour la fonction inline, comme je l'ai indiqué, le compilateur remplacera la séquence
    • push des informations sur la fonction appelante
    • exécution fonction appelée
    • pop des informations sur la fonction appelante
    par... les instructions de la fonction appelée.

    Pour les fonctions template, le compilateur doit attendre de savoir à quoi correspond T pour créer le code exécutable en prenant la bonne taille pour représenter ce T... et réagira exactement comme si la fonction avait été déclarée inline

    Et cela, il ne peut le savoir que... lors de l'appel de ch... dans la fonction qui y fait appel
    Comment faire dans ce cas "particulier" ?

    Merci encore
    Comme tu l'as fait, c'est très bien
    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

  6. #6
    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
    Salut,
    Le rôle d'inline est double : indiquer que le compilateur peut remplacer l'appel de la fonction directement par son code. Le second rôle est d'indiquer que les différentes définitions n'en sont qu'une (sous réserve que ce soit effectivement la même définition). Le linker ne provoque alors pas d'erreur et une seule fonction est bien générée.

  7. #7
    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
    Citation Envoyé par 3DArchi Voir le message
    Salut,
    Le rôle d'inline est double : indiquer que le compilateur peut remplacer l'appel de la fonction directement par son code. Le second rôle est d'indiquer que les différentes définitions n'en sont qu'une (sous réserve que ce soit effectivement la même définition). Le linker ne provoque alors pas d'erreur et une seule fonction est bien générée.
    Oui, effectivement, tu complète ma réponse en prenant en compte le fait que le fait de déclarer une fonction inline ne fait que demander au compilateur de l'inliner...

    Mais cette nuance est surtout importante lorsque l'on parle de performances que l'on croit parfois à tord être supérieure pour les fonctions inline
    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

  8. #8
    Invité
    Invité(e)
    Par défaut
    Merci pour vos réponse, pour ceux à qui ça intéresse, sachez que j'ai posté ce topic, en rapport avec ce topic là : http://www.developpez.net/forums/d88...ement-sources/

    Merci encore à vous

  9. #9
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Citation Envoyé par Abdelite Voir le message
    Merci pour vos réponse,

    Mais si j'ai dans un même fichier (A.hpp) les prototypes et définitions (toujours séparé) d'une même classe A :

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    #ifndef FILE__A
    #define FILE__A
     
    class A
    {
    	public:
    		A();
    		bool uu()
    		inline int tt();
    		template<typename T> T ch(T h = 0);
     
    	protected:
    		bool u;
    		int t;
    		int c;
     
    };
     
    A::A() : u(true), t(8), c(1)
    {
     
    }
     
    bool A::uu()
    {
    	return u;
    }
     
    inline int A::tt()
    {
    	return t;
    }
     
    template<typename T> T A::ch(T h)
    {
    	if(h == 1) return h + c;
    }
     
    #endif //FILE__A
    Et que j'ai deux fichiers sources (.cpp) qui incluent ce même fichier. Il ne risquent pas d'avoir un problème de linker ? Comment faire dans ce cas "particulier" ?

    Merci encore
    En théorie il faudrait définir A() et uu() dans un fichier séparé.

    Par contre, ta fonction inline sera effectivement redéfinie puisqu'elle sera recopiée à chaque occurrence de son appel, mais c'est effectivement ce qu'on attend d'une fonction inline.

    Pour ta fonction Template, Il me semble que le compilateur créera une nouvelle fonction pour chaque jeu de paramètre template différent avec lesquels elle sera appelé, ce qui revien à créer un .cpp a elle ne sera pas définie tant qu'elle n'est pas appvec cette fonction, pour chaque jeu paramètres templates différents avec lesquels tu l'utilise, donc pas de souci

    Bonne continuation

    edit : arf grilled. Par contre, pour les deux non template, ne serait-ce pas mieux de les définir dans un fichier séparé (ou alors le compilo s'en charge ?).

  10. #10
    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
    Citation Envoyé par méphistopheles Voir le message
    En théorie il faudrait définir A() et uu() dans un fichier séparé.
    Oui, évidemment... Au temps pour moi... Je m'étais honteusement laissé aveugler par ch et tt

    A() et uu() poseront problème parce que ce ne sont pas des fonctions inline ni considérées comme, et ton éditeur de liens ne se plaindra pas pour ch et tt, mais bien pour A et uu...

    Si tu veux vraiment mettre ces deux fonctions particulières dans ton fichier d'en-tête, tu devra les définir au sein même de la définition de ta classe...

    Elles seront alors implicitement réputées inline
    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

  11. #11
    Membre Expert
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Oui, évidemment... Au temps pour moi... Je m'étais honteusement laissé aveugler par ch et tt

    A() et uu() poseront problème parce que ce ne sont pas des fonctions inline ni considérées comme, et ton éditeur de liens ne se plaindra pas pour ch et tt, mais bien pour A et uu...

    Si tu veux vraiment mettre ces deux fonctions particulières dans ton fichier d'en-tête, tu devra les définir au sein même de la définition de ta classe...

    Elles seront alors implicitement réputées inline
    Je me disais aussi ...

  12. #12
    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 koala01 Voir le message
    Si tu veux vraiment mettre ces deux fonctions particulières dans ton fichier d'en-tête, tu devra les définir au sein même de la définition de ta classe...
    Ou les définir inline comme la fonction générique.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 08/12/2014, 14h08
  2. Réponses: 6
    Dernier message: 18/02/2013, 16h52
  3. Réponses: 3
    Dernier message: 16/08/2009, 09h29
  4. Séparer la définition et la déclaration d'une classe
    Par prgasp77 dans le forum Langage
    Réponses: 5
    Dernier message: 24/08/2005, 21h37
  5. Définition de "Métalangage"
    Par No dans le forum Langages de programmation
    Réponses: 5
    Dernier message: 19/07/2002, 14h05

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