Bonjour,
Je débute en C++ ainsi qu'en POO depuis quelques jours et j'apprécierai grandement votre aide.
J'aborde actuellement les classes, et en particulier l'utilisation d'opérateurs.
Je me suis imaginé un exercice dans lequel j'ai une classe nommée Monnaie qui a comme variables membres 3 valeurs numériques (livre, shilling, penny) et une string utilisable par un accesseur permettant d'afficher la valeur en texte.
Le soucis vient de l'impossibilité de passer un objet Monnaie issue d'une opération arithmétique directement dans un cout malgré la surcharge de l'opérateur << de ostream. En effet, tout fonctionne dans le programme, sauf la dernière ligne de mon main qui provoque une erreur lors de la compilation (no match for ‘operator<<’ in ‘std::operator<<):
Pourtant, la surcharge de operator<< fonctionne sachant que ceci passe à la compilation et au lancement :
Code : Sélectionner tout - Visualiser dans une fenêtre à part cout << objetMonnaie1 << " + 35 pence = " << objetMonnaie1 + 35 << endl;
C'est donc mon opérateur + qui met apparemment le boxon.
Code : Sélectionner tout - Visualiser dans une fenêtre à part cout << objetMonnaie1 << endl;
Dans la logique du programme, objetMonnaie1 + 35 renvoie pourtant bien un objet de type Monnaie, comme objetMonnaie1...
Voici le code source complet, également fourni en pièce jointe zippée :
(NB: les remarques sur l'amélioration du code pour le reste du programme sont bienvenues)
main.cpp
Monnaie.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
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 #include <iostream> #include "include/Monnaie.h" using namespace std; int main() { Monnaie monArgent(3,45,15); cout << "3 livres 45 shillings 15 pence = " << monArgent.str() << endl; monArgent.vaut(6,19,13); cout << "6 livres 19 shillings 13 pence = " << monArgent.str() << endl; cout << endl; Monnaie tonArgent(4,1); cout << "Ton argent : " << tonArgent.str() << endl; tonArgent.vaut(1); cout << "En fait, ton argent vaut " << tonArgent.str() << endl; cout << endl; Monnaie gain(20,20,20); Monnaie finDeMois(monArgent + gain); cout << "Si je travaillais, je pourrais gagner " << gain.str(); cout << " et avoir un total de " << finDeMois.str() << endl; monArgent += tonArgent; cout << "C'est plus facile de te piquer ton argent, et j'ai maintenant " << monArgent.str(); cout << " en poche" << endl; monArgent /= 2; cout << "Comme je dois partager à part égale avec ma femme, il ne me reste que "; cout << monArgent.str() << "..." << endl << endl; // utilisation de la surcharge sur l'opérateur += Monnaie objetMonnaie1(1,1,1), objetMonnaie2(2,13,11); // - ajout d'un objet Monnaie à un autre cout << objetMonnaie1.str() << " + " << objetMonnaie2.str() << " = "; objetMonnaie1 += objetMonnaie2; cout << objetMonnaie1.str() << endl; // - ajout de 35 pence à un objet Monnaie cout << objetMonnaie1.str() << " + 35 pence = "; objetMonnaie1 += 35; cout << objetMonnaie1.str() << endl; // utilisation de l'opérateur de flux sortant qui réduit à 1 ligne les 3 lignes précédentes cout << objetMonnaie1 << " + 35 pence = " << objetMonnaie1 + 35 << endl; return 0; }
Monnaie.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
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #ifndef MONNAIE_H #define MONNAIE_H #include <string> class Monnaie { public: Monnaie(int livre = 0, int shilling = 0, int penny = 0); ~Monnaie(); void vaut(int livre = 0, int shilling = 0, int penny = 0); std::string str(); Monnaie &operator+=(Monnaie const &autreMonnaie); Monnaie &operator+=(int const pennyEnPlus); Monnaie &operator/=(double const &diviseur); private: int m_livre, m_shilling, m_penny; std::string m_string; }; Monnaie operator+(Monnaie const &monnaie1, Monnaie const &monnaie2); Monnaie operator+(Monnaie const &monnaie, int const pennyEnPlus); /* * À noter que operator+ n'intervient pas sur un objet déjà existant, * n'appartient pas à l'espace de nom Monnaie, * et est déclaré en dehors de la classe comme une simple fonction * basée sur operator+= qui lui appartient à la classe. */ std::ostream& operator<<(std::ostream &fluxSortant, Monnaie &monnaie); #endif // MONNAIE_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
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144 #include "../include/Monnaie.h" #include <sstream> #include <iostream> void format(int &livre, int &shilling, int &penny, std::string &chaine) /* * Conversion livre - shilling - penny * 1 livre = 20 shilling * 1 shilling = 12 penny * * Affectation à une string nommée chaine de * "xx livre(s) xx shilling(s) xx penny/pence" * représentant la valeur de Monnaie */ { // formatage numérique if (penny > 11) { shilling += penny/12; penny %= 12; } if (shilling > 19) { livre += shilling/20; shilling %= 20; } // formatage string // - flux de sortie pour string std::ostringstream fluxSortantString; // - écriture dans le flux if (livre != 0) { fluxSortantString << livre << " livre"; if (livre > 1) {fluxSortantString << "s";} if (shilling != 0 || penny != 0) {fluxSortantString << " ";} } if (shilling != 0) { fluxSortantString << shilling << " shilling"; if (shilling > 1) {fluxSortantString << "s";} if (penny != 0) {fluxSortantString << " ";} } if (penny != 0) { fluxSortantString << penny; if (penny > 1) {fluxSortantString << " pence";} else {fluxSortantString << " penny";} } // - récupération de la string chaine = fluxSortantString.str(); } Monnaie::Monnaie(int livre, int shilling, int penny) : m_livre(livre), m_shilling(shilling), m_penny(penny) { //constructeur format(m_livre, m_shilling, m_penny, m_string); } Monnaie::~Monnaie() { //destructeur vide } void Monnaie::vaut(int livre, int shilling, int penny) { m_livre = livre; m_shilling = shilling; m_penny = penny; format(m_livre, m_shilling, m_penny, m_string); } std::string Monnaie::str() { return m_string; } Monnaie& Monnaie::operator+=(Monnaie const &autreMonnaie) { // ajout des valeurs de autreMonnaie m_livre += autreMonnaie.m_livre; m_shilling += autreMonnaie.m_shilling; m_penny += autreMonnaie.m_penny; // formatage et retour format(m_livre, m_shilling, m_penny, m_string); return *this; } Monnaie& Monnaie::operator+=(int const pennyEnPlus) { // ajout des pennyEnPlus m_penny += pennyEnPlus; // formatage et retour format(m_livre, m_shilling, m_penny, m_string); return *this; } Monnaie operator+(Monnaie const &monnaie1, Monnaie const &monnaie2) /* * operator+ n'intervient pas sur un objet déjà existant et n'appartient pas à l'espace de nom Monnaie */ { // affectation des valeurs de monnaie1 à une copie Monnaie copieMonnaie(monnaie1); // ajout des valeurs de monnaie2 copieMonnaie += monnaie2; // retour (formatage effectué par l'opérateur +=) return copieMonnaie; } Monnaie operator+(Monnaie const &monnaie, int const pennyEnPlus) /* * operator+ n'intervient pas sur un objet déjà existant et n'appartient pas à l'espace de nom Monnaie */ { // affectation des valeurs de monnaie1 à une copie Monnaie copieMonnaie(monnaie); // ajout des valeurs de monnaie2 copieMonnaie += pennyEnPlus; // retour (formatage effectué par l'opérateur +=) return copieMonnaie; } Monnaie& Monnaie::operator/=(double const &diviseur) { // division des valeurs de Monnaie m_livre /= diviseur; m_shilling /= diviseur; m_penny /= diviseur; // formatage et retour format(m_livre, m_shilling, m_penny, m_string); return *this; } std::ostream& operator<<(std::ostream &fluxSortant, Monnaie &monnaie) /* * cout est passé en référence dans fluxSortant * l'objet de type Monnaie est passé en référence dans la variable monnaie */ { fluxSortant << monnaie.str(); // passage dans le flux de monnaie.m_string grace à son accesseur return fluxSortant; }
Partager