Partage
  • Partager sur Facebook
  • Partager sur Twitter

Classes dérivées

Surcharge de fonction

    23 septembre 2007 à 13:48:33

    Bonjour à tous,

    Voila, je suis en train de coder une application en C++ et je me heurte à une difficulté à propos de la surcharge de fonction dans des classes dérivées (si toute fois c’est possible, on ne peut peut-être que redéfinir, auquel cas je veux faire des choses impossibles. . . ).

    Je vais essayer de vous expliquer le plus clairement mon problème.

    J’ai une classe de base que j’ai appelé CObjet, sans entrer dans les détails, chaque objet à un numero pour les traitements et un nom pour les messages à l’écran c’est tout de même plus parlant

    Je peux donc la résumer à ceci :

    1. class CObjet
    2. {
    3. public :
    4. int getNumero() ;
    5. std::string getNom();
    6. protected:
    7. int m_numero;
    8. std::string m_nom;
    9. };

    Jusque là, tout va bien.

    Bien sur tous mes objets ne fonctionnent pas de la même manière et en lisant le dernier chapitre sur le C++, je me suis dit que je pouvais les spécialiser au fur à mesure en les dérivant et ainsi leurs adjoindre des fonctionnalités particulières.

    Entre autre, j’ai des objets qui donnent reçoivent des informations de cartes électroniques, les échanges PC/Cartes se faisant par la liaison série via des micro-contrôleurs(µC), et cerise sur le gâteau, une carte contient plusieurs objet de même type (jusqu’à 8)

    J’ai donc créé une classe CCarte que je résume ainsi pour mon problème :

    1. class CCarte : public CObjet
    2. {
    3. public :
    4. int getCarte();
    5. int getElement();
    6. int getNumero(int carte, int element); // ET C’EST LA QUE CA COÏNCE
    7. protected :
    8. int m_carte;
    9. int m_element
    10. } ;

    Alors je me suis dit, attention M@téo nous à bien dit de me pas confondre surcharge et redéfinition de fonction, j’ai donc surchargé ma fonction dans la classe CObjet en y ajoutant int getNumero(int, int), mais je ne peux l’écrire dans la classe CObjet puisqu’elle ne connaît pas les attributs m_carte et m_element, et j’ai redéfini la fonction dans la classe CCarte et l’écrivant cette fois ci.

    Mais cela n’a pas l’effet que je comptais, la surcharge ne se fait pas et les classes dérivées de CCarte ne connaissent plus que la méthode int getNumero(int carte, int element) et le compilateur grogne lorsque j’utilise la fonction initiale getNumero(), en me signalant qu’il manque des arguments en paramètre.

    Alors bien sur, je peux régler le problème en donnant des noms différents aux deux méthodes, mais comme beaucoup d’entre nous, je suis en pleine découverte et je joue aux apprentis sorciers ou au singe savant, ma question est donc la suivante :

    Citation : Ma question

    Est-il possible de surcharger dans une classe fille une méthode de la classe mère ? si oui comment ?



    • Partager sur Facebook
    • Partager sur Twitter
      23 septembre 2007 à 13:57:08

      quand tu surcharges une méthode, çà "cache" les méthodes ayant le même nom dans la classe mère.
      Donc pour résoudre ton problème tu es OBLIGER de redéfinir getNumero() sans argument
      • Partager sur Facebook
      • Partager sur Twitter
        23 septembre 2007 à 13:59:01

        Je trouve que c'est un très mauvais choix de donner le même nom aux deux méthodes puisqu'elles ne donnent pas le même numéro...

        Je te conseille d'être plus précis dans le nommage de tes méthodes ;)
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          23 septembre 2007 à 14:01:32

          Citation : ミニロプ

          quand tu surcharges une méthode, çà "cache" les méthodes ayant le même nom dans la classe mère.
          Donc pour résoudre ton problème tu es OBLIGER de redéfinir getNumero() sans argument


          Tiens ça m'intrigue...
          Et on peux faire ça (après redéfinition de getNumero dans la définition de CCarte) :
          1. int CCarte::getNumero(int carte, int element)
          2. {
          3.     CObjet::getNumero();
          4. }

          ?
          (C'est un exemple, le sens n'y ai donc pas recherché.)
          • Partager sur Facebook
          • Partager sur Twitter
            23 septembre 2007 à 14:20:25

            Donc en fait je suis obligé de donner deux noms différents à mes méthodes, ce qui va satisfaire le compilateur et Antartika :)

            Si ne je peux passer à la nouvelle méthode la carte et l'element, je ne peux rien faire, il n'y a plus d'intérêt.

            Je dirai tout de même que les deux méthodes donnent le même numéro, on le trouve simplement de deux façons différentes selon que l'on est orienté vers le programme ou vers l'électronique qui elle ne connaît que son numéro de carte et le numéro de l'élément sur la carte.

            Merci pour vos réponses.

            J'édite car je dois attendre 24h00 :-°

            Finalement la synthèse de vos réponses m'a fait trouvé une solution, je redéfini la fonction dans la class CCarte puis je la surcharge de la façon suivante

            1. Dans le .h
            2.     int getNumero();
            3.     int getNumero(int carte, int element);
            4. Dans le .cpp
            5. int CCarte::getNumero()                       // redéfinition
            6. {
            7.     return CObjet::getNumero();
            8. }
            9. int CCarte::getNumero(int carte, int element) // Surcharge
            10. {
            11.     CCarte *Carte = this;
            12.     while((Carte->m_carte != carte) || (Carte->m_element =! element)) Carte++;
            13.     return m_numero;
            14. }


            Voilà, ça marche, encore merci :)
            • Partager sur Facebook
            • Partager sur Twitter
              23 septembre 2007 à 15:24:52

              Je tiens à corriger ce qui a été dit au-dessus.

              Quand on réécrit une fonction membre dans une classe fille qui a la même signature u'une fonction membre de la classe mère, on parle de masquage (et pas de surcharge comme le dit matteo).

              Concernant ton problème, il n'y a aucune raison que ça ne marche pas !!

              Que dit ton compilateur ??

              -----------------------------------------------------
              Sinon, une remarque personelle:
              1) Pourquoi passer un numero et un élément en argument si ce sont déjà des attributs de la classe ?
              • Partager sur Facebook
              • Partager sur Twitter
              Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
                23 septembre 2007 à 15:40:29

                Ahh, je viens d'éditer ma dernière réponse en proposant ce que je viens de trouver.

                Le compilateur masquait bien la méthode d'origine de la classe mère et me signalait donc qu'il me manquait des arguments.

                Citation : Nanoc

                Sinon, une remarque personelle:
                1) Pourquoi passer un numero et un élément en argument si ce sont déjà des attributs de la classe ?



                Parce que lorsque je communique avec l'électronique, elle ne connaît que c'est deux éléments là et ensuite je dois rechercher le numéro de l'objet pour faire le traitement.
                • Partager sur Facebook
                • Partager sur Twitter
                  23 septembre 2007 à 15:49:43

                  Citation : Nanoc

                  Quand on réécrit une fonction membre dans une classe fille qui a la même signature u'une fonction membre de la classe mère, on parle de masquage (et pas de surcharge comme le dit matteo).

                  Concernant ton problème, il n'y a aucune raison que ça ne marche pas !!


                  car çà masque toutes les fonctions qui ont le même nom (sans prendre compte de la signature).
                  • Partager sur Facebook
                  • Partager sur Twitter
                    23 septembre 2007 à 16:20:03

                    Citation : ** Phil **

                    Je dirai tout de même que les deux méthodes donnent le même numéro, on le trouve simplement de deux façons différentes selon que l'on est orienté vers le programme ou vers l'électronique qui elle ne connaît que son numéro de carte et le numéro de l'élément sur la carte.



                    Ha oui dans ce cas elles doivent bien avoir le même nom, mais y'a un truc qui m'échappe :

                    Pourquoi redéfinir cette méthode alors que tu es normalement capable de retrouver le numéro à partir de la méthode de la classe mère ?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      23 septembre 2007 à 17:21:55

                      En fait j'ai des tables de classes dérivants toutes des classes CObjet ou CCarte qui hérite elle-même de CObjet.

                      Dans CObjet, la méthode getNumero() est un simple accesseur qui retourne le m_numero de l'élément sur lequel il pointe.

                      Lorsque je reçois un dialogue d'une carte électronique, elle m'envoie en entête son numero de carte (m_carte), le numero de l'élément sur la carte (m_element) et un type de dialogue, puis vient derrière le message. Pour exploiter le message, je dois me caler dans la table de classe concernée sur le bon élément à l'aide du couple (carte, element).

                      Dans la suite de l'application, ce programme qui a reçu le message doit dialoguer par IP avec d'autres programmes qui eux identifient les objets par leur numéro (m_numero).

                      • Partager sur Facebook
                      • Partager sur Twitter
                        23 septembre 2007 à 18:44:17

                        Ce qui va pas c'est que si CCarte hérite de CObjet alors CCarte a l'attribut m_numero...

                        Sachant que ta méthode getNumero (dans la classe mère) ne prend pas te parametre, il n'y a aucune raison de faire une méthode plus compliquée dans la classe fille...

                        Si t'es capable d'obtenir le numéro avec 0 argument pourquoi créer une méthode qui en prend 2 ?
                        • Partager sur Facebook
                        • Partager sur Twitter
                          23 septembre 2007 à 19:29:49

                          C'est vrai que je peux créer dans la classe CCarte une méthode getAdresse(int carte, int element) qui retourne l'adresse de l'objet correspondant à la carte et à l'élément et ensuite appeler la méthode getNumero().
                          • Partager sur Facebook
                          • Partager sur Twitter
                            23 septembre 2007 à 19:42:37

                            T'as pas bien compris la notion d'héritage je crois...

                            "L'adresse de l'objet correspondant à la carte" et bien c'est l'adresse de la carte elle même (pointeur this...) !

                            Tout ce que tu as à faire c'est :
                            macarte.getNumero();
                            • Partager sur Facebook
                            • Partager sur Twitter
                              23 septembre 2007 à 20:05:27

                              Les objets dépendants d'une carte sont ainsi défini:

                              1. class CmonObjet : public CCarte;
                              2. . . .
                              3. CmonObjet *monObjet;
                              4. . . .
                              5. monObjet = new CmonObjet[nombreObjet];



                              La méthode getNumero n'a de sens que lorsque j'écris monObjet[i].getNumero();

                              Lorsque je reçois un dialogue de carte, je n'ai aucune idée de la valeur qu'il faut donner à i, je ne connais que le numéro de carte et le numéro d'élément.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                23 septembre 2007 à 20:12:23

                                Tu veux faire une recherche dans ton tableau en fait ?
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  23 septembre 2007 à 20:32:44

                                  Voila, et je n'ai pas le choix, comme dit plus haut dans un post. Mais j'ai aussi besoin de la méthode hérité de CObjet :)
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    23 septembre 2007 à 21:01:02

                                    Ben en fait pour moi t'as besoin d'une méthode computeNumber(int carte, int element) qui te donne le numero adequat.

                                    Cette méthode est donc une méthode de classe (on n'a pas forcément besoin de créer un objet pour l'utiliser) => mot clef static.

                                    Ensuite tu utilises ça comme ça:

                                    int num = CCarte::computeNumber(1,2);
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      23 septembre 2007 à 21:14:04

                                      Ahh oui, les méthodes statiques, je dois dire que j'y ai pensé mais j'ai abandonné car il est dit dans le cours qu'elles n'ont pas accès aux attributs de la classe, et moi j'en ai besoin.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Anonyme
                                        23 septembre 2007 à 23:20:36

                                        Salut,

                                        mon intervention ne concerne pas le C++ en tant que tel, mais, d'apres ce que j'ai compris au travers de tes exemples pourquoi vouloir faire heriter à tout prix une carte d'un objet ? Apparement une carte est une collection d'objets, non ? Partant de ca, fais une classe objet (deja fait), une classe carte comme une collection d'objets (à toi de voir l'implementation que tu preferes), et, si tu as plusieurs Cartes, une classe CarteManager etant elle meme une collection de cartes. Les classes collections pouvant avoir des methodes de recherches sur leurs elements. Si les objects dans les cartes sont à specialiser alors créé une classe specifique heritant d'objet mais qui ne sera pas son container (genre ObjectCarte). Bref, en resumé, tu auras un objet specifique à tes cartes (ObjectCarte), une classe CCarte implementant au minimum quelques methodes de collections pour gerer les ObjectCarte(Add, Remove, this[], Find etc), ainsi qu'une class CCartesManager construit selon le meme principe si tu as plusieurs cartes à gerer. Ca devient beaucoup plus simple et intuitif à gerer, tu cherches une CCarte dans un pool de cartes, ensuite tu cherches un ObjectCarte dans la CCarte renvoyé et enfin tu travailles avec ton objet.

                                        "My 2 cents"
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          24 septembre 2007 à 11:52:26

                                          Citation : ** Phil **

                                          Ahh oui, les méthodes statiques, je dois dire que j'y ai pensé mais j'ai abandonné car il est dit dans le cours qu'elles n'ont pas accès aux attributs de la classe, et moi j'en ai besoin.



                                          Sans ton algo pour trouver le nombre c'est dur de savoir...


                                          SirJulio >> t'as peut être bien raison, en fait j'arrive pas à comprendre qu'est ce que c'est que cette classe objet et cette classe carte qui en dérive =D
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Classes dérivées

                                          × 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