Salut,
Commençons déjà par ta classe client...
- void SetNom(string nom)
- void SetPrenom(string prenom)
- void SetId(int id)
sont autant de fonctions inutiles : une fois que tu as définis les membres nom, prénom et id, tu n'as plus à les modifier, sous peine d'avoir un autre client (on pourrait dire que ces trois information te servent d'identifiant unique non ambigu )
En plus, il est toujours préférable de transmettre une chaine de caractères sous la forme d'une référence (constante si elle ne doit pas être modifiée) plutot que par valeur, pour éviter les copies inutiles
void SetAll(string nom,string prenom,string adr,int id,int nb,double total) n'est pas inutile, mais ne devrait pas s'appeler setAll: ce devrait etre le constructeur de ta classe client.
int nb et double total ne seraient d'ailleurs pas nécessaire, car, lorsque le client est créé, il n'a encore fait aucun achat (ce qui fait que nb vaut d'office 0) et n'a encore fatalement rien payé (ce qui fait que total vaut aussi 0.0)
SetNbAchat et SetTotal devraient etre regroupée en une seule fonction qui ne prendrait pas le total "général" mais le total de l'achat que le client vient de faire, et qui ne prendrait pas le nombre d'achat.
Avec ces deux mutateurs, tu te trouves dans l'obligation d'écrire un code proche de
1 2 3
|
client.SetNbAchat(client.GetNbAchat()+1);
client.SetTotal(client.GetTotal() + totalActuel); |
alors que si tu créais à la place une fonction (mettons ajouteAuxAchat) qui serait implémentée sous la forme de
1 2 3 4 5
| ajouteAuxAchat(double totalDesAchatDuJour)
{
totalAchat_ += totalDesAchatDuJour;
++nbAchat_;
} |
il te suffirait d'un
client.ajouteAuxAchat(totalDesAchatDuJour);
pour faire le tout de manière automatique
Enfin,
- string GetNom() const
- string GetPrenom() const
- string GetAdresse() const
devraient renvoyer une référence constante, de nouveau, pour éviter les copies inutiles
De manière générale, tout ce qui n'est pas un type primitif comme char, short, int, long, long long, leur version signed et unsigned, float, double et long double) mérite amplement d'être transmis (ou renvoyé, si faire se peut) par référence (constante, s'il ne faut pas les modifier) pour éviter les copies inutiles.
La raison est simple : la copie de type "complexes" peut demander énormément de ressources, tant en mémoire qu'en temps pour l'effectuer
Ceci étant dit : une classe Client a, typiquement ce que l'on appelle une sémantique d'entité, c'est à dire, qu'il s'agit d'une classe pour laquelle il n'existera jamais deux instances ayant les mêmes valeurs, au moins pour certains de leurs membre (le jour où je crois un philippe dunski qui habite à la même adresse que moi, je le traite de menteur )
Typiquement, il ne sert à rien de comparer deux instances ayant sémantique d'entité "membre à membre", car seuls ceux qui permettent d'identifier une instance de manière unique et non ambigue ont de l'importance.
Par exemple, le membre id est un quandidat idéal : chaque client aura son propre numéro d'id qui sera "unique et non ambigu" (comprend: qui permet d'identifier un client en étant sur que l'on n'en trouvera pas un autre, meme s'il a le meme nom, le meme prénom, mais une adresse ou une date de naissance différente ) De plus, on ne comparera pas deux clients entre eux, car cela n'aurait aucun sens:
Si tu trouve le client qui s'appelle Dupont, Jaques, qui habite au 26 rue de la poupée qui tousse à Makapet - les - bains - de - pieds, qui est venu 36 fois au magasin pour un total dee 856.89€ et (surtout) qui a l'identifiant client 726, tu es sur que c'est la personne que tu cherches...
Sauf que...
Sauf que pour pouvoir obtenir ces informations, il faudrait... que tu aies déjà trouvé monsieur Dupont, Jaques, ayant le numéro de client 726 dans ta liste de clients
Mais, si monsieur Dupont, Jaques (la personne que tu as physiquement en face de toi ou au téléphone, hein ?) pourra très facilement te donner son nom, son prénom et son adresse, tu auras de la chance s'il est en mesure de te donner son numéro de client, beaucoup de chance s'il peut te dire combien de fois (précisément) il est venu chez toi pour acheter, et tu devrais te dépêcher d'aller jouer à l'euromillion s'il arrive à te donner le total de ses achats avec une précision de ne serait-ce que de 10 €
Bref, tu l'auras compris, l'opérateur == ne sert strictement à rien pour les classes ayant sémantique d'entité, simplement parce que cela compare des données qui nécessiteraient que tu aies déjà retrouvé ton client pour arriver à faire la comparaison
Par contre, tu peux comparer certaines informations de manière séparée : le numéro de client avec un numéro que le client t'aura donné, par exemple, ou, s'il s'avère que le client s'est trompé (ou s'il ne le connait simplement pas), un ensemble correspondant à son non, son prénom et son adresse.
Seulement, ce n'est plus un opérateur ==.
L'idéal, dans ce cas là, est de recourir à ce que l'on appelle un foncteur ou un prédicat
Il s'agit d'une petite structure qui ne sera composée que d'une seule fonction (éventuellement un ou deux membres si besoin): l'opérateur () qui, dans le cas qui nous intéresse, renverra un booléen.
Nous pourrions, ainsi, avoir un foncteur qui vérifie le numéro id du client et renvoie vrai s'il correspond à un numéro que nous fournissons, sous une forme proche de
1 2 3 4 5 6 7
| struct equalById
{
bool operator()(Client const & cl, int id) const
{
return cl.GetIdClient() == id;
}
}; |
ou un autre qui compare le nom, le prénom et l'adresse avec des informations également fournies, sous une forme proche de
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| struct equalByName
{
equalByName(std::string const & nom, std::string const & prenom,
std::string adresse):nom(nom),prenom(prenom),adresse(adresse){}
std::string nom;
std::string prenom;
std::string adresse;
bool operator()(Client const & cl) const
{
return cl.GetNom() == nom
&& cl.GetPrenom() == prenom
&& cl.GetAdresse() == adresse:
}
}; |
De cette manière, tu pourrais écrire quelque chose de proche dede
1 2 3 4 5 6 7 8 9 10 11
| int numeroDid; /* donné par le client */
/*pour chaque client dans la liste, */
if (equalById()(client, numeroDid) )
{
// c'est celui qu'on cherche
}
else
{
// c'est pas celui ci
} |
ou de
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| std::string nom; //fourni par le client
std::string prenom; // idem
std::string adresse; // encore idem
equalByName test(nom, prenom, adresse);
/*pour chaque client dans la liste, */
if (test(client) )
{
// c'est celui qu'on cherche
}
else
{
// c'est pas celui ci
} |
et là, enfin, tu aurais quelque chose d'utilisable
Partager