Bonjour ,
le suis débutant en programmation C++ et j'ai du mal à déclarer les opérateurs < et <= en utilisant :*this (l'objet courant).
Est ce que quelqu'un peut m'aider sur ça.
Merci d'avance .
Bonjour ,
le suis débutant en programmation C++ et j'ai du mal à déclarer les opérateurs < et <= en utilisant :*this (l'objet courant).
Est ce que quelqu'un peut m'aider sur ça.
Merci d'avance .
Bonjour,
Il suffit de consulter la section sur la surcharge des opérateurs de la .
En particulier cette entrée : http://cpp.developpez.com/faq/cpp/?p...l-operateur-lt
Je suggère d'écrire une fonction friend compare qui centralise la logique de comparaison de la classe/structure.
La surcharge des opérateurs souhaités est ensuite aisée.
Voici un exemple assez général:
Maintenant, si pour une raison ou une autre on tient absolument à utiliser en cascade les opérateurs déjà surchargés des sous-objets, une solution ressemblerait à ceci:
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 class MyClass { std::string one; int two; //bazar_truc three; public: friend intptr_t compare(MyClass const & l, MyClass const & r) { intptr_t cmp = l.one.compare(r.one); if (cmp == 0) { cmp = (l.two - r.two); //if (cmp == 0) // cmp = compare(l.three, r.three); // etc... } return cmp; } }; inline bool operator<(MyClass const & l, MyClass const & r) { return compare(l, r) < 0; } inline bool operator==(MyClass const & l, MyClass const & r) { return compare(l, r) == 0; } inline bool operator>=(MyClass const & l, MyClass const & r) { return compare(l, r) >= 0; }
Mais je trouve cette autre approche fastidieuse et sujette à erreur s'il faut écrire plusieurs operateurs.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 class MyClass { std::string one; int two; //bazar_truc three; public: bool operator<(MyClass const & v) const { return (this->one < v.one || (!(v.one < this->one) && (this->two < v.two /*|| (!(v.two < this->two) && this->three < v.three)*/))); } };
Il existe une astuce, dont j'ai plus le nom si tenté qu'il y en ait un, pour n'avoir à écrire que 2 opérateurs et que tous les autres se déduisent à partir de ces deux-là : == et <
En théorie il est même possible de n'utiliser que operator< avec bool operator==(const T& l, const T& r) { return !(l < r) && !(r < l); } mais avoir l'implémentation de == peut accélérer les choses selon la complexité de l'opérateur <.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 bool operator==(const T& l, const T& r) { return ...; } bool operator<((const T& l, const T& r) { return ...; } bool operator!=(const T& l, const T& r) { return !(l == r); } bool operator<=(const T& l, const T& r) { return (l == r) || (l < r); } bool operator>(const T& l, const T& r) { return !(l == r) && !(l < r); } bool operator>=(const T& l, const T& r) { return (l == r) || !(l < r); }
Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
Un peu de programmation réseau ?
Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.
C'est même plus simple que ça encore
Voici:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 bool operator==(const T& l, const T& r) { return ...; } bool operator<(const T& l, const T& r) { return ...; } bool operator!=(const T& l, const T& r) { return !(l == r); } bool operator<=(const T& l, const T& r) { return !(r < l); } bool operator>(const T& l, const T& r) { return (r < l); } bool operator>=(const T& l, const T& r) { return !(l < r); }
Merci pour vos réponses.
Je vais utiliser la solution ci-dessus car je dois utiliser *this (l'objet courant). Mais dans mon cas j'ai une classe temps donc je dois comparer heures,minutes et secondes.
Sinon j'ai pas compris ce morceau de code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 return (this->one < v.one || (!(v.one < this->one) && (this->two < v.two /*|| (!(v.two < this->two) && this->three < v.three)*/)));
c'est quoi le one ,two , three ...est ce que je dois mettre à leurs places heure minute et seconde ?
@Camboui> dans l'absolu oui, mais il faut prendre en compte la complexité de l'opérateur== face à l'opérateur<, découper en utilisant == autant que possible peut être bénéfique performencement parlant
C'est vriament l'énoncé ? Et personne ne lui a fait remarquer que ça ne veut rien dire ?je dois utiliser *this
Il veut quoi ? Voir juste un *this apparaître dans le code ?
Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
Un peu de programmation réseau ?
Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.
@Bousk, le but de ma réponse était de donner plus de visibilité à ta proposition .
A propos de performance, je pense qu'elle a lieu à trois moments distincts, tous importants:
-le temps dévolu au développement,
-la vitesse d'exécution du code,
-le temps dévolu à la maintenance.
L'idéal étant de réunir les trois
L'approche que j'ai proposé en passant par une fonction compare réunit les trois me semble-t-il.
Mais notre ami @CANADG veut une solution "académique" pour son operator<, voici une des meilleures je crois:
Simple, lisible et performante. Et elle utilise this
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 return ((((this->heure * 64) + this->minute) * 64) + this->seconde) < ((((v.heure * 64) + v.minute) * 64) + v.seconde);
Et oui, j'ai bien multiplié par 64 et non 60, c'est exprès. Et il n'y a aucun branchement conditionnel, c'est aussi exprès.
Salut,
De manière générale, il y a deux possibilités :
Soit on compare l'objet courant à "un autre", sous une forme qui serait proche desoit on utilise des fonctions libres pour la comparaison, sous une forme proche de
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 class MaClasse{ public: /* ... */ bool operator ==(MaClasse const &) const; bool operator <(MaClasse const &) const; bool operator >(MaClasse const &) const; bool operator <=(MaClasse const &) const; bool operator >=(MaClasse const &) const; private: /* ... */ };
Dans le premier cas, comme il s'agit de fonctions membres, les opérateurs ont forcément accès à l'ensemble des membres de la classe, et this est implicite, si bien qu'une code proche de
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 class MaClasse{ public: /* ... */ private: /* ... */ }; bool operator ==(MaClasse const &, MaClasse const &) const; bool operator <(MaClasse const &, MaClasse const &) const; bool operator >(MaClasse const &, MaClasse const &) const; bool operator <=(MaClasse const &, MaClasse const &) const; bool operator >=(MaClasse const &, MaClasse const &) const;est tout à fait similaire au code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 bool MaClasse::operator == (MaClasse const & other) const{ return membre1 == other.membre1 && membre2 == other.membre2; }
Par contre, si on n'envisage de fournir que des fonctions libres, il n'y a pas d'objet courant (vu qu'il y a... l'objet qui correspond à l'opérande de gauche et celui qui correspond à l'opérande de droite), et il peut être intéressant de déclarer au minimum l'opérateur < et (éventuellement) l'opérateur == comme étant ami(s) de la classe.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 bool MaClasse::operator == (MaClasse const & other) const{ return this->membre1 == other.membre1 && this->membre2 == other.membre2; }
Maintenant, il est aussi possible de combiner les deux et d'avoir les opérateurs sous forme de fonction membre ET sous forme de fonction libre.
Dans ce cas, l'implémentation des opérateurs sous forme de fonction membre feront sans doute (au moins pour < et == ) appel aux membres de la classe, et les version sous forme de fonction libre feront appel à la version sous forme de fonction membre, sous une forme qui serait au final proche de
Il faut enfin savoir que les opérateurs prenant la forme de fonctions libres présentent de sérieux avantages, entre autres en termes de symétrie (par exempe : s'il existe une conversion possible entre un type quelconque et notre classe).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 class MaClasse{ public: /* je ne met que celui- là pour l'exemple*/ bool operator ==(MaClasse const &) const; }; bool MaClasse::operator == (MaClasse const & other) const{ return this->membre1 == other.membre1 && this->membre2 == other.membre2; } bool operator(MaClasse const & c1, MaClasse const & c2){ return c1.operator==(c2); }
En effet, si on considère qu'il est possible de convertir implicitement un int en un objet du type MaClasse, un code proche desera toujours autorisé, mais un code proche de
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 int main(){ MaClasse c; if(c == 10) { // conversion implicite de 10 en un objet de type MaClasse /* ... */ } }
ne sera autorisé que si l'opérateur existe sous la forme d'une fonction libre (et, bien sur, il en va de même pour tous les opérateurs de comparaison, ainsi que pour les opérateurs mathématiques, d'ailleurs)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 int main(){ MaClasse c; if(10 == c) { // conversion implicite de 10 en un objet de type MaClasse /* ... */ } }
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
La comparaison multi-membres peut également être fait à travers std::tie.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 namespace detail { auto as_tuple(const T& o) { return std::tie(o.member1, o.member2); } } bool operator==(const T& l, const T& r) { return detail::as_tuple(l) == detail::as_tuple(r); } bool operator<(const T& l, const T& r) { return detail::as_tuple(l) < detail::as_tuple(r); }
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager