Partage
  • Partager sur Facebook
  • Partager sur Twitter

Surcharge de l'opérateur ==

problème de paramètres

    27 mars 2008 à 18:07:03

    Salut,

    après l'opérateur de flux >>, je suis passé à la surcharge de l'opérateur de comparaison == , et voila j'ai un problème avec le prototype en fait :

    1. ZString operator==(const ZString &chaine,const ZString &chaine) const;


    le problème c'est qu'il me faut 2 paramètres , comme je dois comparer deux chaines entre elles ! Et le compilo me répond :

    'ZString ZString::operator ==(const ZString &chaine,const ZString &chaine)' must take exactly one argument ....

    donc voila, comment je fais ??
    • Partager sur Facebook
    • Partager sur Twitter
      27 mars 2008 à 18:15:36

      C'est un bool que tu dois renvoyer ...
      Et la fonction doit être libre! Pas membre.
      • Partager sur Facebook
      • Partager sur Twitter
      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
        27 mars 2008 à 18:37:15

        je dois renvoyer un bool ... cool mais je vois pas trop en quoi ça réponds à ma quetion o_O tu pourrais m'expliquer ton raisonnement ??

        et pourquoi diable cette fonction devrait elle être libre ? pourtant les autres surcharges sont membres !! o_O
        • Partager sur Facebook
        • Partager sur Twitter
          27 mars 2008 à 18:48:12

          euh d'accord mais ils ne donnent que le prototype ... ça ne m'aide pas vraiment !
          • Partager sur Facebook
          • Partager sur Twitter
            27 mars 2008 à 18:56:01

            1. class ZString
            2. {
            3.    // ... (operator[] peut etre utile !)
            4. };
            5. // libre pour des raisons de symetrie (c'est lmghs qui le dit, alors c'est que ce doit etre juste, meme si je comprends pas trop)
            6. bool operator==(const ZString &A, const ZString &B)
            7. {
            8.    // ta comparaison
            9. }


            edit: enfaite si lmghs pouvait nous eclaircir sur la symetrie, sinon bah je vais chercher de mon coté
            • Partager sur Facebook
            • Partager sur Twitter
              27 mars 2008 à 18:59:43

              Le prototype donné dans le lien au dessus fonctionne :
              exemple :
              1. #include <iostream>
              2. class Test {
              3. public :
              4.         Test(int init);
              5.         bool operator==(const Test &) const;
              6.         int attribut;
              7. };
              8. Test::Test(int init) {
              9.         attribut=init;
              10. }
              11. bool Test::operator==(const Test &toCompare) const {
              12.         if(this->attribut==toCompare.attribut) return true;
              13.         else return false;
              14. }
              15. int main (int argc, char * const argv[]) {
              16.         Test first(15);
              17.         Test second(15);
              18.         Test third(22);
              19.         if(first==second) std::cout << "first=second" << std::endl;
              20.         if(first==third) std::cout << "first=third"<< std::endl;
              21.         else std::cout << "first!=third"<< std::endl;
              22.     return 0;
              23. }

              Citation : Console C++


              first=second
              first!=third



              • Partager sur Facebook
              • Partager sur Twitter
                27 mars 2008 à 19:03:27

                tu fais des comparaisons entre le pointeur this->attribut et une chaine de caractère .. dans mon cas comment ferais-je ? à quoi correspond 'attribut' ?
                • Partager sur Facebook
                • Partager sur Twitter
                  27 mars 2008 à 19:10:49

                  Citation

                  tu fais des comparaisons entre le pointeur this->attribut et une chaine de caractère .. dans mon cas comment ferais-je ? à quoi correspond 'attribut' ?



                  Non, je compare deux entier. Pour toi "attribut" est ton attribut char* m_chaine qui contient ta chaîne.

                  Je ferais :
                  1. bool ZString::operator==(const ZString &toCompare) const {
                  2.         if(this->m_chaine==toCompare.m_chaine) return true;
                  3.         else return false;
                  4. }


                  Avec comme prototype :

                  1. bool operator==(const ZString &) const


                  • Partager sur Facebook
                  • Partager sur Twitter
                    27 mars 2008 à 19:16:21

                    problème : ça tient pas debout ! Ben oui comme ce n'est pas une fonction membre, elle ne eut pas utiliser "this" et n'as pas accès à m_chaine ... et ne peut pas être const non plus .
                    • Partager sur Facebook
                    • Partager sur Twitter
                      27 mars 2008 à 19:20:03

                      En membre, il y a toujours un argument suplémentaire implicite. Donc, 2 + 1 = 3. Pas pratique pour comparer deux choses.
                      Donc 2 solutions
                      1- membre à un seul argument explicite
                      2- libre à deux arguments explicites.

                      La seconde est meilleure que la première pour des raisons de symétrie -- pas besoin de rajouter une version libre qui prend un const char* et un ZString, dans cet ordre. C'est à dire que si ton constructeur d'initialisation/conversion n'est pas déclaré "explicit", tu pourras écrire indifféremment:
                      1. const bool eq1 = "toto" == maZString;
                      2. const bool eq2 = maZString == "toto" ;
                      3. const bool eq3 = maZtring1 == maZString2;

                      La version membre n'autorise que 2 et 3 (vu que l'argument implicite ne peut être que le premier d'un opérateur membre), tandis que la version libre supporte les 3 tests.
                      Bref, c'est symétrique. Et c'est pour cela que je critique systématiquement l'écriture des opérateurs binaires en membre : c'est enseigner un truc qui s'assimile à une perte de temps vu que c'est l'autre version qu'il faut préférer.
                      (Je suis allé vite, c'est traité plus en détails dans Guru Of the Week je crois).

                      PS: un autre truc avec lequel j'ai du mal, c'est avec les déclinaisons de
                      1. if (exprBooleenne)
                      2.     return true;
                      3. else
                      4.     return false;

                      alors qu'un simple
                      1. return exprBooleenne;
                      fait parfaitement l'affaire.
                      Apprennez à manipuler des expressions booléennes.

                      PS: les const char* se comparent (entre autres), avec strcmp().
                      • Partager sur Facebook
                      • Partager sur Twitter
                      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                        27 mars 2008 à 19:21:43

                        Mais c'est une fonction membre, regarde au moins le code que je te donne. :o
                        Si tu veux une alternative tu peux l'utiliser comme fonction libre mais il faut la déclarer amie pour qu'elle puisse accéder aux attributs :

                        Comme ceci :
                        1. #include <iostream>
                        2. class Test {
                        3. public :
                        4.         Test(int init);
                        5.         friend bool operator==(const Test &, const Test &);
                        6. private:
                        7.                 int attribut;
                        8. };
                        9. Test::Test(int init) {
                        10.         attribut=init;
                        11. }
                        12. bool operator==(const Test &compared,const Test &toCompare) {
                        13.         if(compared.attribut==toCompare.attribut) return true;
                        14.         else return false;
                        15. }
                        16. int main (int argc, char * const argv[]) {
                        17.         Test first(15);
                        18.         Test second(15);
                        19.         Test third(22);
                        20.         if(first==second) std::cout << "first=second" << std::endl;
                        21.         if(first==third) std::cout << "first=third"<< std::endl;
                        22.         else std::cout << "first!=third"<< std::endl;
                        23.     return 0;
                        24. }


                        A toi de voir laquelle tu préfère.

                        edit :

                        Citation : lmghs


                        PS: un autre truc avec lequel j'ai du mal, c'est avec les déclinaisons de
                        ...
                        alors qu'un simple
                        ...
                        fait parfaitement l'affaire.
                        Apprennez à manipuler des expressions booléennes.



                        C'est vrai, merci lmghs. :)


                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 mars 2008 à 19:28:29

                          désolé xs-yann j'ai mal regaardé le prototype ! lol ... en effet ce que tu dis lmgs c'est très pertinent je l'avoue ^^ et pour xs-yann merci beacoup

                          UP : @ lmghs : ton idée de la méthode externe est bien mais du coup elle n'est pas appellée lors d'une comparaison de ZString ...
                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 mars 2008 à 19:40:54

                            Citation : darkangel75

                            UP : @ lmghs : ton idée de la méthode externe est bien mais du coup elle n'est pas appellée lors d'une comparaison de ZString ...


                            o_O
                            Quoi ?
                            Et pourquoi donc
                            1. bool operator(ZString const& lhs, ZString const& rhs);
                            ne serait pas appelée sur
                            1. const bool eq = maZString1 == maZString2;
                            ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                            C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                              27 mars 2008 à 19:41:49

                              merci lmghs pour ces precisions

                              @darkangel75: implémenter strcmp() n'est pas dur (il me semble que c'etait en exercice dans le cours sur les chaines de charactère) et c'est pour ca que j'ai dit que op[]() pouvait etre utile

                              edit:

                              Citation : darkangel75

                              UP : @ lmghs : ton idée de la méthode externe est bien mais du coup elle n'est pas appellée lors d'une comparaison de ZString ...


                              et op<<() tu crois que ca marchais comment ?
                              1. std::ostream& operator<<(std::ostream& Out, const ZString &Other);
                              2. bool          operator==(const ZString &Lhs, const ZString &Rhs);
                              • Partager sur Facebook
                              • Partager sur Twitter
                                27 mars 2008 à 20:10:49

                                o_O c'est vrai ça .. je vais revoir ça
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  28 mars 2008 à 17:04:16

                                  @lmghs : merci pour tes explications sur la symétrie, je viens de découvrir et de comprendre un truc que je ne connaissais pas.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    31 mars 2008 à 0:08:25

                                    Bonsoir Darkangel,

                                    Pour la réponse du TP de Mateo en C++,
                                    à la question de la surcharge de l'opérateur de comparaison ==,
                                    voici ma solution, en calquant sur sa trame et son style ;) :

                                    Dans la classe ZString, les prototypes des 2 méthodes suivantes :

                                    1. bool operator==(const ZString &chaine);
                                    2. bool operator==(const char *chaine);


                                    Et l'implémentation de ces méthodes dans le fichier source correspondant :

                                    1. bool ZString::operator==(const ZString &chaine)
                                    2. {   int compteur = 0;
                                    3.     for (int i = 0; i < m_longueur; i++)
                                    4.         if (chaine.m_chaine[i] == m_chaine[i])
                                    5.             compteur++;
                                    6.     if (compteur == m_longueur)
                                    7.         return true;
                                    8.     else
                                    9.         return false;}
                                    10. bool ZString::operator==(const char *chaine)
                                    11. {   int compteur = 0;
                                    12.     for (int i = 0; i < m_longueur; i++)
                                    13.         if (chaine[i] == m_chaine[i])
                                    14.             compteur++;
                                    15.     if (compteur == m_longueur)
                                    16.         return true;
                                    17.     else
                                    18.         return false;}


                                    Il n'y a donc qu'un seul paramètre pour chacune des méthodes comme dans l'exemple du cours.
                                    Les méthodes ne sont pas libres mais bel et bien des membres de notre classe dans ce cas.
                                    Je trouve cela plus propre d'ailleurs :p .
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      31 mars 2008 à 0:51:13

                                      Il te manque donc une définition (symétrie oblige!) et des const.

                                      /me adepte du DRY (je dis ça pour le code dupliqué, pas parce que tu n'as pas lu ce que j'ai écris -- NB il y a duplications dans std::string pour raisons d'optimisation je suppose)

                                      Au fait, il y a des dépassements de buffer dans tes fonctions -- il faut interdire d'ajouter '\0' pour les prévenir par effet de bord.

                                      J'avais failli ne pas retrouver le mot sur les interfaces généralisés sur GOTW (c'est aussi traité dans XC++ ; et regarder les liens en bibliographie, en particulier le 1er). Et j'ai aussi le document de Stepanov à te proposer: http://www.stepanovpapers.com/notes.pdf (p21)

                                      (Vu qu'il y en a 2-3 ici qui commencent à se cultiver, j'ai lâché les liens. Interro écrite dans 6 mois ^^ )
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.

                                      Surcharge de l'opérateur ==

                                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                      • Editeur
                                      • Markdown