Séparer la définition et déclaration d'une classe? (gcc) [résolu]

Séparer la définition et déclaration d'une classe? (gcc) [résolu] - C++ - Programmation

Marsh Posté le 07-05-2003 à 18:29:23    

bonjour tt le monde  
bon voilà g une question tt conne.  
je voudrais séparer l'interface d'une classe (sa déclaration) de sa définition càd avoir d'une part un fichier client.h et de l'autre un fichier client.cpp parce qu'à la longue ça commence à devenir lourd tt ds le mm fichier  :cry:  
bon j'y arrive parfaitement avec VC++ mais avec gcc non, avec les mm sources pourtant.
ce qui marche avec VC++ :
->client.h
     -rien de particulier juste la définition
->client.cpp
     -#include "client.h"
     -tt la définition des méthodes
->programme principale
     -#include "client.h"
Comment on fait pour que dissocier les 2 avec gcc? :??:
merci


Message édité par Niala le 08-05-2003 à 12:06:21
Reply

Marsh Posté le 07-05-2003 à 18:29:23   

Reply

Marsh Posté le 07-05-2003 à 18:31:04    

comme ça [:spamafote]
 
Si tu mettais ton message d'erreur, on y verrait plus clair


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 07-05-2003 à 18:42:19    

Code :
  1. [niala@niala Comptes]$ ./compile
  2. In file included from /usr/include/c++/3.2.2/backward/iostream.h:31,
  3.                  from main.cpp:1:
  4. /usr/include/c++/3.2.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <sstream> instead of the deprecated header <strstream.h>. To disable this warning use -Wno-deprecated.
  5. /tmp/ccDQzBlK.o(.text+0x53a): In function `main':
  6. : undefined reference to `CClient::getProfile()'
  7. collect2: ld returned 1 exit status
  8. ./compile: line 5: ./main: No such file or directory


 
voilà... y'a bien un avertissement mais j'y comprends pas grand chose à vrai dire  :(  

Reply

Marsh Posté le 07-05-2003 à 18:43:55    

Au début il te dit d'utiliser <iostream> plutot que <iostream.h>.
Ensuite donne ton makefile, il doit etre mal organisé...

Reply

Marsh Posté le 07-05-2003 à 18:45:31    

skeye a écrit :

Au début il te dit d'utiliser <iostream> plutot que <iostream.h>.
Ensuite donne ton makefile, il doit etre mal organisé...


 
makefile!:??:  
dsl j'suis à la rue là  :sleep:
 

Reply

Marsh Posté le 07-05-2003 à 18:46:38    

Niala a écrit :


 
makefile!:??:  
dsl j'suis à la rue là  :sleep:
 


tu le compiles comment ton prog?

Reply

Marsh Posté le 07-05-2003 à 18:52:36    

g++ -o main main.cpp
 
c ce qu'il y'a ds le ./compile + l'éxécution du prog
 
c juste un ti prog d'application des classes faut dire aussi  :sweat:  

Reply

Marsh Posté le 07-05-2003 à 18:56:50    

Niala a écrit :

g++ -o main main.cpp
 
c ce qu'il y'a ds le ./compile + l'éxécution du prog
 
c juste un ti prog d'application des classes faut dire aussi  :sweat:  
 


Il faut que tu dises au compilateur d'où sort ta classe CClient...
En gros ca donnera plutot:
g++ -c main.cpp
g++ -c CClient.cpp
g++ main.o CClient.o -o main
 
En supposant que ta classe CClient soit dans les fichiers CClient.cpp et CClient.hpp...

Reply

Marsh Posté le 07-05-2003 à 19:12:58    

skeye a écrit :


Il faut que tu dises au compilateur d'où sort ta classe CClient...
En gros ca donnera plutot:
g++ -c main.cpp
g++ -c CClient.cpp
g++ main.o CClient.o -o main
 
En supposant que ta classe CClient soit dans les fichiers CClient.cpp et CClient.hpp...


 
ça veut tjrs pas mais pour d'autres raison surdéfinition g l'impression.
 

Code :
  1. [niala@niala Comptes]$ g++ -o main main.o client.o
  2. client.o(.text+0x0): In function `CCompte::CCompte[not-in-charge](int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, float)':
  3. : multiple definition of `CCompte::CCompte[not-in-charge](int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, float)'
  4. main.o(.text+0x0): first defined here
  5. client.o(.text+0x82): In function `CCompte::CCompte[in-charge](int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, float)':
  6. : multiple definition of `CCompte::CCompte[in-charge](int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, float)'
  7. main.o(.text+0x82): first defined here
  8. client.o(.text+0x104): In function `CCompte::setSuivant(CCompte*)':
  9. : multiple definition of `CCompte::setSuivant(CCompte*)'
  10. main.o(.text+0x104): first defined here
  11. client.o(.text+0x112): In function `CCompte::getNum()':
  12. : multiple definition of `CCompte::getNum()'
  13. main.o(.text+0x112): first defined here
  14. client.o(.text+0x11c): In function `CCompte::getSuivant()':
  15. : multiple definition of `CCompte::getSuivant()'
  16. main.o(.text+0x11c): first defined here
  17. client.o(.text+0x128): In function `CCompte::getDetails()':
  18. : multiple definition of `CCompte::getDetails()'
  19. main.o(.text+0x128): first defined here
  20. client.o(.text+0x1d8): In function `CCompte::getDescriptif()':
  21. : multiple definition of `CCompte::getDescriptif()'
  22. main.o(.text+0x1d8): first defined here
  23. client.o(.text+0x1fe): In function `CCompte::getDebit()':
  24. : multiple definition of `CCompte::getDebit()'
  25. main.o(.text+0x1fe): first defined here
  26. client.o(.text+0x212): In function `CCompte::Debiter(float)':
  27. : multiple definition of `CCompte::Debiter(float)'
  28. main.o(.text+0x212): first defined here
  29. client.o(.text+0x250): In function `CCompte::Crediter(float)':
  30. : multiple definition of `CCompte::Crediter(float)'
  31. main.o(.text+0x250): first defined here
  32. collect2: ld returned 1 exit status


 

Reply

Marsh Posté le 07-05-2003 à 19:24:53    

include client.h  
seulement dans le client.cpp

Reply

Marsh Posté le 07-05-2003 à 19:24:53   

Reply

Marsh Posté le 07-05-2003 à 19:34:33    

dag elg a écrit :

include client.h  
seulement dans le client.cpp


 
si j'inclus pas client.h à main.cpp il va râler parce qu'il va me dire qu'il connait pas la classe CClient non? :??:

Reply

Marsh Posté le 07-05-2003 à 19:42:39    

bon ça marche maintenant...
en fait il fallait include client.cpp ds main.cpp et non client.h :sleep:, ce dernier étant inclus ds client.cpp. un petit g++ -o main main.cpp et ça marche.
ça me parait tt à coup logique mais pourquoi ça marchait sur VC++ alors que ct le client.h qui était inclus à main.cpp? :??: il en fait qu'à sa tête ou il a rectifié le tir de lui mm?
 
voilà et merci pour votre aide les gars au moins maintenant c sera plus clair :d
 :hello:  

Reply

Marsh Posté le 07-05-2003 à 19:43:24    

Niala a écrit :


 
si j'inclus pas client.h à main.cpp il va râler parce qu'il va me dire qu'il connait pas la classe CClient non? :??:
 


Si.
Tu as mis un bloc #ifndef / #define/ #endif à ton .h ?

Reply

Marsh Posté le 07-05-2003 à 19:43:28    

essaye d'encapsuler ta definition de classe dans :

Code :
  1. #ifndef _CLIENT_H_
  2. #define _CLIENT_H_
  3. // ta definition
  4. #endif

 
 
en gros (si je me trompe pas) ca dis a ton compilo de prendre une fois le code correspondant a client.cpp pour linker !

Reply

Marsh Posté le 07-05-2003 à 19:44:43    

Niala a écrit :

bon ça marche maintenant...
en fait il fallait include client.cpp ds main.cpp et non client.h :sleep:, ce dernier étant inclus ds client.cpp. un petit g++ -o main main.cpp et ça marche.
ça me parait tt à coup logique mais pourquoi ça marchait sur VC++ alors que ct le client.h qui était inclus à main.cpp? :??: il en fait qu'à sa tête ou il a rectifié le tir de lui mm?
 
voilà et merci pour votre aide les gars au moins maintenant c sera plus clair :d
 :hello:  
 


 :non:  
On n'inclut pas un .cpp!!
Si tu n'y arrives pas donnes ton code qu'on puisse comprendre d'où ca vient...

Reply

Marsh Posté le 07-05-2003 à 19:46:04    

lerenard a écrit :

essaye d'encapsuler ta definition de classe dans :

Code :
  1. #ifndef _CLIENT_H_
  2. #define _CLIENT_H_
  3. // ta definition
  4. #endif

 
 
en gros (si je me trompe pas) ca dis a ton compilo de prendre une fois le code correspondant a client.cpp pour linker !


Grillaid :D
En fait ca dit au pré-processeur de ne pas prendre en compte ce que ca encapsule s'il l'a déjà vu passer...

Reply

Marsh Posté le 07-05-2003 à 19:51:30    

skeye a écrit :


 :non:  
On n'inclut pas un .cpp!!
Si tu n'y arrives pas donnes ton code qu'on puisse comprendre d'où ca vient...


 
bah ça marche comme ça c grave?  :sweat:  

Reply

Marsh Posté le 07-05-2003 à 19:51:32    

je veux bien te croire je connais pas bien cette partie des compilos. Mais toujours est-il que c'est comme ca que je fais pour inclure plusieurs fois le meme fichier a des endroits differents du projet et ce marche.

Reply

Marsh Posté le 07-05-2003 à 19:57:26    

Niala a écrit :


 
bah ça marche comme ça c grave?  :sweat:  
 


Si ca marche tant mieux, mais j'ose même pas imaginer ce que ca donnerait sur un vrai projet...
Si tu veux apprendre à faire des choses propres tu devrais commencer dès maintenant!
Essaye ce que disait lerenard, c'est ce dont je parlais plus haut...et ca devrait résoudre ton pb.
Si ce n'est pas le cas poste ton code, encore une fois c le meilleur moyen d'avoir de l'aide!

Reply

Marsh Posté le 07-05-2003 à 19:59:29    

lerenard a écrit :

je veux bien te croire je connais pas bien cette partie des compilos. Mais toujours est-il que c'est comme ca que je fais pour inclure plusieurs fois le meme fichier a des endroits differents du projet et ce marche.


J'ai pas dit que ca marchait pas!
J'ai juste dit "grillaid", ce qui signifie que je l'avais dit plus haut! :whistle:

Reply

Marsh Posté le 07-05-2003 à 20:10:38    

skeye a écrit :


J'ai pas dit que ca marchait pas!
J'ai juste dit "grillaid", ce qui signifie que je l'avais dit plus haut! :whistle:  


 
autant pour moi...
mais bon nos posts ont 4 secondes d'ecart j'avais pas vu !
pour une fois que j'arrive a poster qqc tant pis...

Reply

Marsh Posté le 07-05-2003 à 22:34:36    

skeye a écrit :


Si ca marche tant mieux, mais j'ose même pas imaginer ce que ca donnerait sur un vrai projet...
Si tu veux apprendre à faire des choses propres tu devrais commencer dès maintenant!
Essaye ce que disait lerenard, c'est ce dont je parlais plus haut...et ca devrait résoudre ton pb.
Si ce n'est pas le cas poste ton code, encore une fois c le meilleur moyen d'avoir de l'aide!


 
bah je sais pas non plus pour le projet de grande ampleur parce que quand on débute qu'est ce que tu veux on est con!  :(  
bon j'vais aller chercher du côté de
    #ifndef / #define/ #endif  
 
et pi pour mon code franchement c tellement bête que g presque honte de le poster. juste un truc pour mettre en oeuvre le principe de classe voilà...
Allez merci de votre aide
 
PS: simple question
pourquoi les #include "client.h" et/ou #include "client.cpp" sont à proscrire?

Reply

Marsh Posté le 08-05-2003 à 07:37:59    

Les include, ca sert - en gros - a mettre une liste de déclarations ( pas de définitions ) en commun avec plusieurs .cpp. Lorsque tu fais un include, il se contente tout simplement de recopier le corps du fichier inclus dans le fichier courant.
 
Le but de la séparation d'un projet en plusieurs fichiers, c'est précisement d'éviter d'avoir a tout recompiler des que tu modifies un truc qui n'est pas d'une importance capitale pour tout ton programme.  
 
Malheureusement, si tu modifies un fichier qui est inclus dans trois autres fichiers, il te faudra recompiler ces trois autres fichiers. Or dans ton cas, tu dis que ca marche mais regarde ce qui se passe : en fait le compilateur vois ton main.cpp comme un gros fichier cpp contenant le client.cpp et le main.cpp. Et que finalement, une modif dans l'un des deux fichiers t'oblige a tout recompiler... Evidemment, dans ton cas ca n'est pas tres grave, mais tu peux aisement comprendre pourquoi c'est la catastrophe sur des projets d'une plus grand envergure...
 
Donc ce que je te conseille de faire :
 
Dans les .h : ( interface )
- Toujours commencer, comme cela a été indiqué plus haut, par une directive évitant une multi-inclusion
- Jamais de déclarations de variables, sauf en extern
- Toutes les déclarations de classes y sont, mais sans les définitions des fonctions membres
 
Dans les .cpp : ( implémentation )
- Inclure le .h correspondant
- Inclure les .h correspondant a des librairies ( stdio.h, etc...)
- Mettre les définitions des fonctions membres, sans oublier que comme tu n'es plus dans l'espace de noms de ta classe, il te faut les référencer ainsi : MonType CClient::MaFonction()
 
Dans le .cpp ( programme principal )
- Inclure tous les .h nécessaires ( interface + librairies )
 
Chaque .cpp est compilé indépendamment des autres. Ce n'est qu'au linkage que vont s'établir les dépendances. Ainsi, aucun cpp ne doit se baser sur le contenu d'un autre cpp.
 
Si tu n'as pas tout compris, n'hésite pas a demander des précisions...

Reply

Marsh Posté le 08-05-2003 à 08:47:58    

Merci de ton explication Ace
 

Ace17 a écrit :


Le but de la séparation d'un projet en plusieurs fichiers, c'est précisement d'éviter d'avoir a tout recompiler des que tu modifies un truc qui n'est pas d'une importance capitale pour tout ton programme.  


 
c vrai que à mon niveau je voyais juste la séparation de fichier comme un moyen d'avoir un code plus lisible en séparant chaque partie du programme. Qd t'as un programme qui prend 5s pour être compilé t'as pas vraiment comme souci de compiler le moins de chose possible à chaque modification. :) Maintenant j'essaierai d'y penser car c vrai que ça fait plus propre. :d
 
 

Ace17 a écrit :


 Dans les .h : ( interface )
- Toujours commencer, comme cela a été indiqué plus haut, par une directive évitant une multi-inclusion
- Jamais de déclarations de variables, sauf en extern
- Toutes les déclarations de classes y sont, mais sans les définitions des fonctions membres
 
Dans les .cpp : ( implémentation )
- Inclure le .h correspondant
- Inclure les .h correspondant a des librairies ( stdio.h, etc...)
- Mettre les définitions des fonctions membres, sans oublier que comme tu n'es plus dans l'espace de noms de ta classe, il te faut les référencer ainsi : MonType CClient::MaFonction()
 
Dans le .cpp ( programme principal )
- Inclure tous les .h nécessaires ( interface + librairies )
 
Chaque .cpp est compilé indépendamment des autres. Ce n'est qu'au linkage que vont s'établir les dépendances. Ainsi, aucun cpp ne doit se baser sur le contenu d'un autre cpp.


 
donc je dois en fait garder mon fichier main.cpp avec #include client.h. Le fichier client.cpp incluera lui client.h.
il ne me restera plus alors  qu'à indiquer les directives de multi-inclusion ds les .h.
et puis si g bien compris lors de la compilation aprés la modifition du client.cpp (par exemple) je devrai uniquement faire cela:

Code :
  1. g++ -c client.cpp
  2. g++ main.o client.o -o main


puisque le main.cpp a déjà été compilé.
 
bon avec ces précisions je pense avoir compris le fondement des directives de multi-inclusion. ça me parait maintenant clair et je vous en remercie. n'hésitez pas à me dire si j'écris des conneries hin ;)
 
je vais tester ça ds la journée.
 
Merci  
 :hello:


Message édité par Niala le 08-05-2003 à 08:49:55
Reply

Marsh Posté le 08-05-2003 à 11:57:56    

T'as tout compris!  :hello:

Reply

Marsh Posté le 08-05-2003 à 12:05:23    

:d
allez les gars merci de votre aide alors.  [:alucard]

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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