mais pourquoi mettre un .cpp pour chaque classe? je n'y comprend plus rien
Version imprimable
mais pourquoi mettre un .cpp pour chaque classe? je n'y comprend plus rien
bah, c'est la façon la plus simple, la plus classique, plus logique et la plus mieux bien de développer en C++:
pour chaque classe:
un fichier .h dans lequel tu déclare ta classe
ex: fichier A.h
un fichier .cpp dans lequel tu implémente ta classe:Code:
1
2
3
4
5
6
7
8
9
10
11 #ifndef _A_H_ #define _A_H_ class A{ A(); //le constructeur int GetValue(); //une methode int m_iValue; //une variable membre } #endif
ex: fichier A.cpp
ensuite, dans si ton main utilise une classe A, il faudra ajouter #include "A.h" dans ton main.Code:
1
2
3
4
5
6
7
8 #include "A.h" A::A(){} //le constructeur int A::GetValue() { return m_iValue; }
De manière générale, si tu utilise une classe dans un fichier, tu devra inclure le .h correspondant. Si tu utilise la MFC, beaucoup de classes sont définies dans stdafx.h, tu n'auras donc pas besoin d'inclure les classes "de base" tels CString par ex.
donc ça me ferai 3.h et 4.cpp avec le main...
Je vais tester tout cela mais je suis un débutant dans la programmation, tout ce qui est dit dans ce sujet n'a pas marché jusque là...
Ma classe etagere appelle un objet 'genre', ma classe genre appelle des objets 'etagere' et 'livre' et ma classe livre appelle un objet 'genre'.
Le flou persiste à 2 endroit : - la création de fichiers .h et .cpp
- L'appel de classes dans d'autres classes
je vais tout recommencer, donc l'étape à suivre est un fichier .h et .cpp par classe, un fichier .cpp pour le main
des #ifndef et #endif dans chaque fichier .h
et les déclarations anticipées de classes.
Est-ce exact ?
exactCitation:
Envoyé par Contrec
exactCitation:
Envoyé par Contrec
exactCitation:
Envoyé par Contrec
La déclaration de ta classe, c'est le .h.Citation:
Envoyé par Contrec
Arghh, je viens de voir un erreur dans le code que je t'ai donné: il ne faut pas oublier le ; à la fin de la déclaration de ta classe:
class A
{
...
};
Franchement si ça marche... je te dois le respect car j'ai perdu espoir mais je suis obligé de continuer pour mon BTS
Le fichier .cpp de chaque classe doit contenir les méthodes de la classe ou juste l'implémentation?
tu utilise quel environnement? visual6?
Oui le studio 6, mon programme va etre assez petit donc je ne voudrai pas tout compliquer pourquoi?
l'implémentation. Regarde bien l'exemple que je t'ai donné précédemment.Citation:
Envoyé par Contrec
dans le .h, tu déclare
dans le .cpp, tu implétemente
ça ne marche pas du tout...
Je peux laisser l'ensemble de mon code pour expertise (il n'y en a pas beaucoup) STP ?
ok, vas-y. Juste un truc: sépare bien chaque fichier et indique le nom de chacun.
alors c'est parti :
Classe etagere (fichier etagere.h) :
Classe etagere (fichier etagere.cpp) :Code:
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 // Classe Etagere // #ifndef _ETAGERE_H_ #define _ETAGERE_H class etagere { private: int numero; int nbgenre; genre tabgenre[100]; public : void init(int numEtagere); int retourne_Etagere(); }; int etagere::retourne_Etagere() { return numero; } #endif
Classe genre (fichier genre.h) :Code:
1
2
3
4
5
6
7 #include "etagere.h" void etagere::init(int numEtagere) { numero = numEtagere; }
Classe genre (fichier genre.cpp) :Code:
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 // Classe Genre // #ifndef _GENRE_H_ #define _GENRE_H_ class genre { private: char* libelle; int nblivre; livre tablivre[100]; etagere ob_etagere; public: void init( char* libelleGenre, etagere uneEtagere); char* retourne_genre(); int rangLivre (char* titreLivre); int titre_comp; void placeLivre (livre unLivre); }; char* genre::retourne_genre() { return libelle; } int genre::rangLivre(char* titreLivre) { int i; for (i = 0, i <= 100, i++) { titre_comp = tablivre[i].getTitre while ((i <= nblivre) && (titre_comp < titreLivre)) { i++; } return i; } } void placeLivre(livre unLivre) { int pos = 0; int i = pos; int rangLivre (unLivre.titre); for (i = pos; i<= nblivre; i++) { tablivre[i] = tablivre[i+1]; } tablivre[pos] = unLivre; } #endif
Classe livre (fichier livre.h) :Code:
1
2
3
4
5
6
7
8 #include "genre.h" void genre::init(char* libelleGenre, etagere uneEtagere) { tablivre = 0; strcpy(libelle, libelleGenre); ob_etagere = uneEtagere; }
classe livre (fichier livre.cpp) :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 // Classe Livre // #ifndef _LIVRE_H_ #define _LIVRE_H_ class livre { private : char* titre; genre leGenre; public : void init(char* titreLivre, genre unGenre); char* getTitre (); }; char* livre::getTitre() { return titre; } #endif
Programme principal (fichier Main.cpp) :Code:
1
2
3
4
5
6
7 #include "livre.h" void livre::init(char* titreLivre) { strcpy (titre, titreLivre); leGenre = unGenre; }
Voilà c'est tout, tu risque de voir des abérations dans mon code, j'en suis désolé, il doit y avoir au moins 50 fautes...Code:
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 #include<iostream.h> // cin et cout // #include<string.h> // strcpy pour chaîne de caractères // #include<stdio.h> // gets pour chaîne de caractères // #include "etagere.h" #include "genre.h" #include "livre.h" void main() { int numEtagere; char* libelleGenre; char* titreLivre; int action; char* libelle_s; char* titre_s; int num_etagere_s; etagere uneEtagere; livre unLivre; cout<< "Que voulez-vous faire ?" cout<<"\n\n"; cout<<"\t"; cout<<"1 : Creer une nouvelle etagere."; cout<<"\n"; cout<<"\t"; cout<<"2 : Creer un nouveau genre."; cout<<"\n"; cout<<"\t"; cout<<"3 : Creer un nouveau livre."; cout<<"\n\n"; cin >> action switch (action) { case 1: cout<< "Veuillez entrez le numero de l'etagere à creer SVP."; cout<< "\n\n"; cin >> numEtagere; etagere.init (numEtagere); cout<< "Vous avez cree l'etagere numero :"; cout<<"\n"; num_etagere_s = etagere.retourne_Etagere(); cout<< "\n"; numEtagere = 0; break; case 2: cout<< "Veuillez entrez le libelle du nouveau genre ainsi que le numero de l'etagere SVP."; cout<< "\n\n"; cin >> libelleGenre; cin >> numEtagere; uneEtagere.init(numEtagere); genre.init (libelleGenre, uneEtagere); cout<< "Vous avez cree le genre :"; cout<< "\n"; libelle_s = genre.retourne_genre(); cout<< "\n"; numEtagere = 0; libelleGenre = ""; break; case 3: cout<< "Veuillez entrer le titre du nouveau livre ainsi que son genre SVP."; cout<< "\n\n"; cin >> titreLivre; cin >> libelleGenre; livre.init(titreLivre, libelleGenre); cout<< "Vous avez cree le livre :"; cout<< "\n"; titre_s = livre.getTitre(); cout<< "\n"; titreLivre = ""; libelleGenre = ""; break; } }
Merci de ta patience
je te réponds plus tard, dans la soirée.
ok
C'est vraiq ue c'est problématique:
1. livre a besoin de connaitre la taille de genre pour la déclaration "genre leGenre;", donc sa définition complète
2. Pour définir genre, il faut connaitre la taille de livre pour la déclaration "livre tablivre[100];", donc sa définition complète
=> cercle vicieux.
Moi, je construirais mes objets sur le tas.
C'est-à-dire que ceci ...
... serait remplacé par cela:Code:
1
2
3
4
5
6 genre leGenre; ... livre tablivre[100]; ... genre tabgenre[100];
Pourquoi ? Car là on n'a pas besoin de connaître la taille, il suffit juste de déclarer les classes, sans les définir totalement:Code:
1
2
3
4
5
6 genre* leGenre; ... livre* tablivre[100]; ... genre* tabgenre[100];
Exemple avec etagere.h :
Bien sur cela complique la gestion de la mémoire, mais de toutes façons, les objets sont faits pour être alloués sur le tas et non pas sur la pile (sauf pour les tous petits objets).Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 // Classe Etagere // #ifndef _ETAGERE_H_ #define _ETAGERE_H class genre; // <- nouveau class etagere { private: int numero; int nbgenre; genre* tabgenre[100]; // changement ....
:roll: il faut repenser tout le programme.Citation:
Envoyé par Contrec
(comme dit rolkA --> include multiple = cercle vicieux)
et il faut revoir également
- les include
- les ;
- les conventions de nommage
- les boucles
- char* / std::string
- std::vector
- les constructeurs, les accesseurs, les modifieurs
...
j'ai bien essayé de "rafistoler" le code, mais comme je ne sais pas exactement ce que tu veux faire c'est bof.
http://membres.lycos.fr/bigboomshaka...ar-gif-311.gif Enjoy yourself !
Excuse-moi, j'avais du taf urgent à finir...
ok, c'est un bon début.
1/ je dois savoir comment tu as créé ton projet. Est-ce que tu utilise la MFC?
2/ IL NE DOIT PAS Y AVOIR DE CODE DANS TES .H!!!!
ça c'est du code:
il faut donc le mettre dans le .cppCode:
1
2
3
4 int etagere::retourne_Etagere() { return numero; }
ça c'est la déclaration:
il ne doit y avoir QUE les déclarations dans ton .hCode:int retourne_Etagere();
3/ Il y a quelques erreurs (il s'agit peut-être de fautes de copier/coller ou de fautes de frappes):
#ifndef _ETAGERE_H_
#define _ETAGERE_H_ (tu as oublié le dernier _ )
4/ n'utilise pas de char*.Le char* est la première source d'erreur et de prises de têtes interminables.Citation:
Envoyé par divers membres de dvp
Si tu utilise la MFC, utilise des CString, sinon, des string(std). C'est pour ça qu'il est important de savoir quelle lib tu utilise (MFC ou std). Ce sera ton premier exercice: savoir quelle lib tu utilise :D
Je suis d'accord. Mais à mon sens, le plus simple est de revoir un peu la conception de ce programme. Est-tu obligé d'utiliser cette structure?Citation:
Envoyé par rolkA (je me suis pas trompé ;)
5/ il ya des erreurs d'algo dans tes fonctions, mais on va déjà essayer de compiler, le reste, on verra après.
Mwais... :roll: Si on veut des accesseurs ayant un coût nul, on les met inline... Mettre le code des accesseurs dans une en-tête n'est pas un tragédie :PCitation:
Envoyé par r0d
Le reste me paraît aussi important: MFC (CString) ou librairie standard du C++ (std::string) ? En tout cas pas C (char*)...
oui il me semble que j'ai vu ça quelquepart également :lol:Citation:
Envoyé par r0d
si on connaissait les besoins, on pourrait te guider pour la conception des classes.
http://membres.lycos.fr/bigboomshaka...ar-gif-311.gif Enjoy yourself !
Je suis d'accord, mais pour l'instant, le mieux pour lui est de faire simple, donc d'appliquer des règles simples. Visiblement, il débute en C++, il ne faut donc pas cpmmencer à lui parler des subtilités de ce langage. Non?Citation:
Envoyé par rolkA