Déclaration de classe

Déclaration de classe - C++ - Programmation

Marsh Posté le 09-12-2008 à 18:06:44    

Bonjour,

 

J'ai actuellement une classe définie comme suit :

 

foo.h

Code :
  1. class Foo
  2. {
  3. public:
  4.   Foo();
  5.   ~Foo();
  6.   doSmth();
  7. private:
  8.   FooPriv m_fooPriv;
  9. };
 

Et un fichier bar.cpp qui utilise ma classe Foo :

Code :
  1. #include "foo.h"
  2. Foo foo;
  3. ...
 

Le problème est que je dois également inclure la déclaration de la classe FooPriv dans bar.cpp, chose que je ne veux pas.

 

Ce que je veux, c'est qu'en incluant foo.h, bar.cpp ne "voit" que l'interface de ma classe Foo, et pas les éventuelles variables privées qu'elle peut utiliser pour faire sa cuisine.

 


Est-ce qu'il existe une technique pour éviter ce genre de désagrément ?

Message cité 1 fois
Message édité par Riot le 09-12-2008 à 18:07:50

---------------
Be the one with the flames.
Reply

Marsh Posté le 09-12-2008 à 18:06:44   

Reply

Marsh Posté le 09-12-2008 à 19:53:01    

Riot a écrit :


Le problème est que je dois également inclure la déclaration de la classe FooPriv dans bar.cpp, chose que je ne veux pas.


Aucune raison de le faire, sinon c'ets que tu t'es vautré avant.

Reply

Marsh Posté le 09-12-2008 à 20:25:28    

et genre foo.h inclue pas foo_priv.h ???

Reply

Marsh Posté le 09-12-2008 à 20:39:38    

je vois pas le rapport o_O

Reply

Marsh Posté le 10-12-2008 à 08:59:41    

Cacher l'implémentation, ok ! Mais là il est question de cacher l'interface si j'ai bien compris.


Message édité par kao98 le 10-12-2008 à 08:59:49

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 10-12-2008 à 09:37:53    


Oui mais non. Le problème sera de toute façon le même. Quand j'incluerai foo.h à partir de bar.cpp, le compilo dira qu'il ne connait pas la classe FooPriv.
 

Joel F a écrit :

et genre foo.h inclue pas foo_priv.h ???


Justement non.


---------------
Be the one with the flames.
Reply

Marsh Posté le 10-12-2008 à 10:06:03    

Pour reprendre et essayer d'être plus clair, je dispose des 3 fichiers suivants :
 
foo.h qui déclare la classe Foo (ce fichier ne comporte pas d'autre code, et plus particulièrement : il n'inclut pas foo_priv.h)

Code :
  1. class Foo
  2. {
  3. public:
  4.   Foo();
  5.   ~Foo();
  6.   doSmth();
  7. private:
  8.   FooPriv m_fooPriv;
  9. };


 
foo_priv.h qui déclare la classe FooPriv (ce fichier ne comporte pas d'autre code)

Code :
  1. class FooPriv
  2. {
  3. public:
  4.   FooPriv();
  5.   ~FooPriv();
  6.   doSmthPriv();
  7. };


 
Et un fichier bar.cpp qui utilise ma classe Foo :

Code :
  1. #include "foo.h"
  2. Foo foo;
  3. ...


 
Bien sûr en l'état actuel, ça ne peut pas compiler correctement.
On part du principe que bar.cpp n'a aucune raison de connaître la classe FooPriv.
Du coup comment dois-je me débrouiller ?


---------------
Be the one with the flames.
Reply

Marsh Posté le 10-12-2008 à 10:07:14    

inclure fooPriv.h dans foo.h !
Tu cherches à faire ou à masquer quelque chose en particulier ? Parce que sinon, je ne vois pas le problème !


Message édité par kao98 le 10-12-2008 à 10:07:43

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 10-12-2008 à 10:11:21    

Si dans foo.h, tu n'inclues pas foo_priv.h, cela ne compileras pas (et cela n'a rien à voir avec le code dans bar.cpp), le compilateur a besoine de connaître la taille de l'objet FooPriv pour connaître la taille à allouer pour Foo.
 
Si tu ne veux pas inclure foo_priv.h dans foo.h, la solution proposée par Drizzt_dOo_urden (FooPriv*) est la bonne dans ce cas (où utiliser des smart pointers). Sinon tu n'a pas le choix, tu dois obligatoirement inclure foo_priv.h dans foo.h.

Reply

Marsh Posté le 10-12-2008 à 15:20:50    

Effectivement, tu as complètement raison. Merci beaucoup :jap:
 
 
Mais par contre, est-ce qu'il y a une solution pour les variables qui ne sont pas des pointeurs ?


---------------
Be the one with the flames.
Reply

Marsh Posté le 10-12-2008 à 15:20:50   

Reply

Marsh Posté le 10-12-2008 à 15:24:59    

Riot a écrit :


Mais par contre, est-ce qu'il y a une solution pour les variables qui ne sont pas des pointeurs ?


Hein ?


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 10-12-2008 à 17:34:40    

Code :
  1. class Foo
  2. {
  3. public:
  4.   Foo();
  5.   ~Foo();
  6.   doSmth();
  7. private:
  8.   FooPriv m_fooPriv;
  9. };


 
et pas

Code :
  1. class Foo
  2. {
  3. public:
  4.   Foo();
  5.   ~Foo();
  6.   doSmth();
  7. private:
  8.   FooPriv* m_pFooPriv;
  9. };


---------------
Be the one with the flames.
Reply

Marsh Posté le 10-12-2008 à 17:38:54    

Ben, ça ne change rien ! C'est pareil !!
 
Faudrait que tu revois les bases là quand même !


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 10-12-2008 à 18:23:15    

T'es sûr que c'est pareil?
Moi je dirais que mr simon a raison.
 

mr simon a écrit :

Si dans foo.h, tu n'inclues pas foo_priv.h, cela ne compileras pas (et cela n'a rien à voir avec le code dans bar.cpp), le compilateur a besoine de connaître la taille de l'objet FooPriv pour connaître la taille à allouer pour Foo.
 
Si tu ne veux pas inclure foo_priv.h dans foo.h, la solution proposée par Drizzt_dOo_urden (FooPriv*) est la bonne dans ce cas (où utiliser des smart pointers). Sinon tu n'a pas le choix, tu dois obligatoirement inclure foo_priv.h dans foo.h.


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 10-12-2008 à 19:26:48    

Mais du moment que tu inclues foo_priv.h dans foo.h, le compilo, il connait la taille de l'objet !
Après, que tu déclares un pointeur ou une variable, ça ne change strictement rien !


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 10-12-2008 à 22:42:51    

kao98 a écrit :

Mais du moment que tu inclues foo_priv.h dans foo.h, le compilo, il connait la taille de l'objet !
Après, que tu déclares un pointeur ou une variable, ça ne change strictement rien !


 
Bah çà change un peu quand même. Si tu as une classe avec beaucoup de membres nécessitant beaucoup d'include, à chaque fois que tu voudras utiliser l'objet Foo, et donc que tu inclues foo.h, le compilo va analyser tout les points .h, et çà peut rallonger, significativement, le temps de compilation.
Ceci est surtout vrai pour des grosses librairies (type boost).
 
D'autre part, si foo_priv.h est souvent modifié, alors tout les fichiers incluant foo.h seront recompilés. Donc je dirais qu'il faut peser le pour et le contre entre utiliser un objet ou une pointer sur cet objet (utilisation de smart pointer).

Reply

Marsh Posté le 10-12-2008 à 23:30:40    

salut, tu peux faire une interface qui expose ce que tu veux exposer de Foo
une implémentation de Foo qui contient ce que tu veux 'cacher'
(c'est le but des interfaces [classes abstraites])
 
le CPP qui va faire l'instanciation de Foo_impl devra inclure le .H 'complet' de Foo_impl
les autres juste le .H de l'interface
 
IFoo.h
---
class IFoo
{
  protected:
    IFoo();
    virtual ~IFoo();
  public:
    virtual void DoSmthg() = 0;
};
---
 
Foo.h
---
#include "IFoo.h"
#include "pouet.H"
class Foo: public IFoo
{
  public:
    Foo();
    ~Foo();
    void DoSmthg();
  private:
    pouet m_pouet;
};
---
 
fichier qui instancie.cpp
---
#include "Foo.h" // du lourd
Foo * toto = new Foo();
---
 
fichier qui utilise.cpp
---
#include "IFoo.h" // léger
void func(IFoo * object)
{
   objet->DoSmthg();
}


---------------
troc http://forum.hardware.fr/hfr/Achat [...] 3557_1.htm troc http://forum.hardware.fr/hfr/Achat [...] 3580_1.htm
Reply

Marsh Posté le 11-12-2008 à 07:37:31    

mr simon a écrit :


 
Bah çà change un peu quand même. Si tu as une classe avec beaucoup de membres nécessitant beaucoup d'include, à chaque fois que tu voudras utiliser l'objet Foo, et donc que tu inclues foo.h, le compilo va analyser tout les points .h, et çà peut rallonger, significativement, le temps de compilation.
Ceci est surtout vrai pour des grosses librairies (type boost).
 
D'autre part, si foo_priv.h est souvent modifié, alors tout les fichiers incluant foo.h seront recompilés. Donc je dirais qu'il faut peser le pour et le contre entre utiliser un objet ou une pointer sur cet objet (utilisation de smart pointer).


Mais, de toute façon, que ce soit pour déclarer un pointeur ou un objet, il faut inclure foo_priv.h !
Donc que tu déclare un pionteur ou un objet, ça ne change strictement rien concernant la compilation ou l'inclusion de ton .h !
 
Pis, optimiser le temps de compilation ... y'a plus important avant d'en arriver là quand même !


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 11-12-2008 à 09:07:30    

Bah non justement, si tu as simplement un pointeur, tu n'inclues pas le .h mais tu déclare juste la classe:

Code :
  1. class FooPriv;

.
 
Certe il y a plus important, mais quand tu as une application conséquente, gagner quelques minutes (voir plusieurs) n'est pas négligeable.

Reply

Marsh Posté le 11-12-2008 à 09:17:14    

Ho pinaise. Je viens de relire avec le doit depuis le début, j'étais complètement à côté de la plaque.
Désolé !  [:tinostar]


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 11-12-2008 à 10:59:42    


En fait j'ai une contrainte de programmation qui m'interdit d'inclure des .h dans des .h. On peut trouver ça con, mais c'est comme ça ; j'ai pas le choix.
Du coup à chaque fois que j'inclus foo.h, je dois aussi inclure les .h dont dépend foo.h.
 
De plus, ça me pose un problème de conscience ( :o ) que les fichiers qui incluent foo.h voient les modules que peut utiliser pour sa cuisine perso la classe Foo.


---------------
Be the one with the flames.
Reply

Marsh Posté le 11-12-2008 à 11:26:08    

Riot a écrit :


En fait j'ai une contrainte de programmation qui m'interdit d'inclure des .h dans des .h.  


J'aimerais bien savoir pourquoi (sans rire)
 

Riot a écrit :


De plus, ça me pose un problème de conscience ( :o ) que les fichiers qui incluent foo.h voient les modules que peut utiliser pour sa cuisine perso la classe Foo.


PIMPL ou Handle-Body et voila

Reply

Marsh Posté le 11-12-2008 à 14:42:14    

Joel F a écrit :


J'aimerais bien savoir pourquoi (sans rire)


On m'avait donné l'explication, mais j'étais pas du tout convaincu. Là je m'en rappelle plus.
 

Joel F a écrit :


PIMPL ou Handle-Body et voila


Cool, merci.


---------------
Be the one with the flames.
Reply

Marsh Posté le 12-12-2008 à 14:00:13    

Tiens à ce propos:  
 
http://www.gotw.ca/gotw/028.htm


---------------
You can't start a fire with moonlight
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed