Partage
  • Partager sur Facebook
  • Partager sur Twitter

appel d'une fonction externe

Sujet résolu
    31 juillet 2019 à 4:14:57

    bonjour : j'ai un petit probléme , j'ai une fonction au dehors de mes deux
    int distance(int x, int y)
    {
      return abs(x - y);
    }
    
    
    class a {
    protected: position;
    public :
    int pos(){return position;}
    };
    class b :public a {
    private:position ;
    public: 
    int pos(){return position ;}
    void base ( a& autre){ 
    distance(position(),autre.position() );}
    };

    classe et je veux l'appeler mais ça ne marche pas
    • Partager sur Facebook
    • Partager sur Twitter
      31 juillet 2019 à 7:55:45

      Tu appelles la FONCTION position, au lieu d'appeler la donnée membre das ton code.

      Essaie ça :

      void base(a& autre){
          distance(this->position,autre.position);
      }


      Au passage, ta fonction base() retourne void, donc la valeur de la fonction distance() n'est jamais utilisée.

      • Partager sur Facebook
      • Partager sur Twitter
        31 juillet 2019 à 10:01:11

         salut

        dans la suite de remarques de  @Zaap98

        -les parenthèses dans ce cas permettent d'appeler une fonction et non des données membres.

        -le c++ a un typage statique donc il faut donné le type de tes données

        int position;
        //au lieu de
        positon

        - il faut prendre la peine d'indenter son code : un exemple

        int distance(int x, int y)
        {
            return abs(x - y);
        }
        
        
        class a
        {
        protected:
            int position;
        public :
            int pos() {return position;}
        };
        
        class b :public a
        {
        private:
            int position ;
        public:
            int pos() {return position ;}
            
            void base ( a& autre) {distance(pos(),autre.pos() );}
        };




        • Partager sur Facebook
        • Partager sur Twitter
          31 juillet 2019 à 15:08:10

          j'ai essayé ça mais toujours ça ne marche pas il m'affiche ces erreurs ! j'ai appelé la donné membre mzis je ne sais pas ou esr le probleme ! 

          • Partager sur Facebook
          • Partager sur Twitter
            31 juillet 2019 à 15:43:35

            Salut,

            Holàlà!!!! Y a de la place pour le progres, là :p

            Pourquoi déclares tu une donnée membre (dans l'accessibilité privée) nommée position dans la classe b alors que la classe b hérite de la classe a?

            De la même manière, pourquoi déclares (et définis) tu une fonction pos dans la classe b alors que la classe b hérite de la classe a, et que la fonction en question de la classe a n'est pas déclarée virtuelle ?

            Il faut bien comprendre que, si tu fais hériter une classe (nommons la "classe dérivée", par facilité) d'une autre (nommons la "classe de base"), tout ce qui compose la classe de base (ses données membres et ses fonctions membre) fait obligatoirement partie de la classe dérivée.

            Il n'y a donc aucune raison de (re)déclarer une donnée qui existe dans la classe de base (ta classe a) au niveau de la classe dérivée (ta classe b).  Et, surtout, il n'y a aucune raison de changer l'accessibilité de cette donnée.

            De la même manière, il n'y a absolument aucune raison (*) de (re)déclarer une fonction qui existe dans la classe de base (ta classe a) dans la classe dérivée (ta classe b), vu qu'elle existe déjà pour la classe dérivée. Et c'est d'autant plus vrai si le comportement de la fonction en question est, finalement, totalement identique.

            (*) Dans certains cas, on peut prévoir que le comportement d'une fonction soit différent pour la classe dérivée que pour la classe de base; mais, pour pouvoir redéfinir ce comportement dans la classe dérivée, il faut impérativement déclarer cette fonction comme étant virutelle (en faisant précéder le type de retour de la fonction du mot clé virutal )

            De plus, lorsqu'une fonction membre (comme ta fonction pos() ) renvoie clairement la valeur d'une des données membres qui composent la classe, il est généralement "de bon ton" de veiller à ce que cette fonction soit déclarée comme constante pour indiquer au compilateur que la fonction ne modifiera en aucun cas l'instance de la classe à partir de laquelle elle a été appelée.

            En outre, dans ta fonction base, tu essaye d'appeler la fonction (libre) distance en lui transmettant la valeur renvoyée par une fonction position ... qui n'existe absolument pas (c'est la fonction pos qui existe, ou, alors, tu transmet la valeur de la donnée membre position, il faut choisir ;) )

            Sans oublier que les valeurs des données membres positions ne sont jamais définies (et qu'il est, en l'état, impossible de les définir depuis "l'extérieur" des classes, vu que l'une d'elle est dans l'accessibilité privée et que l'autre est dans l'accessibilité protégée).  Le résultat renvoyé par la fonction libre distance risque donc d'être quelque peu ... surprenant ;)

            Enfin, c'est généralement une très mauvaise idée de placer une donnée membre dans l'accessibilité protégée, surtout si cette donnée est rendue accessible au travers d'une fonction qui permet de la récupérer (comme ta fonction pos() ).

            Et j'allais oublier le principal : tu fais appel à la fonction distance, qui va gentiment te renvoyer une valeur que tu ne penses même pas à récupérer et dont tu ne fais absolument rien dans la fonction (base, quel drole de nom) qui y fait appel. C'est donner du travail complètement inutile au processeur :p

            Au final, ton code devrait sans doute ressembler à quelque chose comme

            /* la fonction libre */
            int distance(int a, int b){
                return abs(a-b);
            }
            
            class a{
            public:
                /* pour que la positon soit définie à la construction
                 * de l'instance de a
                a(int p):position{p}{
                }
                int pos() const{
                    return position;
                }
            private:
                int position;
            };
            class b:public a{
                /* la classe b dispose d'office de la donnée position
                 * et de la fonction pos... pas besoin de les rajouter
                 */
            public:
                /* pour pouvoir construire la partie de b qui
                 * correspond à a
                 */
                b(int p):a{p}{
                }
                void base(a const & other) const{//base ne modifie pas les  instances
                    /* on récupère le résultat renvoyé par distance
                     */
                    int result = distance(pos(), other.pos());
                    /* et, tant qu'à faire, on en fait quelque chose
                     */
                    std::cout<<"la distance est de "<<result<<"\n";
                    /* NOTA:  on aurait pu se passer de récupérer
                     * result sous une forme proche de
                     std::cout<<"la distance est de "
                              <<distance(pos, other.pos())<<"\n";
                     */
            };
            
            /* pour voir ce qu se passe */
            int main(){
                a obja{15};
                b objb{20};
                b.base(a);
                return 0;
            }

            Pour conclure, le code que je viens de te présenter est, certes, beaucoup plus correct, mais il est encore conceptuellement erroné, car les classes qui interviennent dans une hiérarchie de classes (ce qui est le cas de la classe a et de la classe b) ont -- typiquement -- sémantique d'entité. Mais ca, c'est une autre histoire ;)

            • Partager sur Facebook
            • Partager sur Twitter
            Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
              31 juillet 2019 à 19:29:20

              koala01  

              oh merci beaucoup pour ces excellents remarques et conseils , en ce qui concerne la déclaration de l'attribut position qui est hérité de la classe mére , c une faute sans faire attention je l'ai pas fait dans mon code principal , donc pour la fonction distance ya tjr un probleme de compliateur , il me prend àà la fonction distance et il m'affiche tjr les erreurs que j'ai publier dans ma derniére réponse , je ne comprends pas ou est le probleme , si vous pouvez tester votre code il va te donner le meme probleme ! 

              • Partager sur Facebook
              • Partager sur Twitter
                31 juillet 2019 à 20:51:52

                AMHA, tu ne montre que la fin de toutes les erreurs émises par le compilateur, et tu devrais donc remonter beaucoup plus haut dans cette liste pour trouver la toute première erreur qui survient.

                Il arrive en effet "régulièrement" que le compilateur  "perde les pédales" lorsqu'il est confronté à une erreur, et qu'il en vienne à considérer "tout ce qui suit" comme ... d'autres erreurs, alors que ce n'en sont pas (des "faux positifs", en quelque sorte ;) ). 

                Le fait de corriger la toute première erreur a donc régulièrement comme résultat "assez surprenant" de... corriger toutes les autres (qui n'en sont pas, en réalité)

                Mais je peux te garantir que, si tu fais un copier coller du code

                // permet de faire appel à std::cout
                #include <iostream>
                int distance(int a, int b){
                    return abs(a-b);
                }
                 
                class a{
                public:
                    a(int p):position{p}{
                    }
                    int pos() const{
                        return position;
                    }
                private:
                    int position;
                };
                class b:public a{
                public:
                    b(int p):a{p}{
                    }
                    void base(a const & other) const{
                        int result = distance(pos(), other.pos());
                        std::cout<<"la distance est de "<<result<<"\n";
                };
                
                int main(){
                    a obja{15};
                    b objb{20};
                    b.base(a);
                    return 0;
                }

                dans un fichier d'implémentation (mettons: main.cpp) (j'ai supprimé les commentaires pour la facilité) et que tu essaye de le compiler, tu n'auras pas la moindre erreur ;)

                • Partager sur Facebook
                • Partager sur Twitter
                Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                  31 juillet 2019 à 21:39:08

                  koala01 

                  voilà j'ai copié votre code et j'ai les erreurs suivantes :

                  • Partager sur Facebook
                  • Partager sur Twitter
                    31 juillet 2019 à 22:03:54

                    pourrais tu faire un copier coller du code (complet) que tu utilises (en utilisant le bouton en forme de </> qui se trouve juste au dessus de la zone d'édition), ainsi qu'un copier / coller (de la même manière) de l'ensemble des erreurs que tu obtiens plutôt que de nous montrer une image qui ne nous dit absolument rien?

                    Pour info, comme tu utilises visiblement CodeBlocks, en cliquant droit sur une des ligne  du log, tu devrais avoir une option te permettant de copier l'ensemble des erreurs qui sont survenues (copy all ou quelque chose du genre) ;)

                    Pour une raison inconnue (pour l'instant) il semblerait, à voir le code qui est présenté ici, que le compilateur soit parti dans un des fichiers d'en-tête de la bibliothèque standard, mais, sans voir ton code à toi, il sera difficile de savoir ce qui ne va pas ;)

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                      1 août 2019 à 1:11:15

                      koala01 une remarque ; lorsque j'ai modifié le nom de la fonction distance à dist ça a été marché bien , mais avec la distance il m'envoi a une fonction dans la bib standarde ..

                      ||=== Build file: "no target" in "no project" (compiler: unknown) ===|

                      C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\stl_iterator_base_types.h||In instantiation of 'struct std::iterator_traits<int>':|

                      C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\stl_iterator_base_funcs.h|114|  required by substitution of 'template<class _InputIterator> typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = int]'|

                      C:\Users\Soheib\Desktop\coursera c++\tesst.cc|83|required from here|

                      C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\stl_iterator_base_types.h|168|error: 'int' is not a class, struct, or union type|

                      C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\stl_iterator_base_types.h|169|error: 'int' is not a class, struct, or union type|

                      C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\stl_iterator_base_types.h|170|error: 'int' is not a class, struct, or union type|

                      C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\stl_iterator_base_types.h|171|error: 'int' is not a class, struct, or union type|

                      C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\stl_iterator_base_types.h|172|error: 'int' is not a class, struct, or union type|

                      ||=== Build failed: 6 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|



                      • Partager sur Facebook
                      • Partager sur Twitter
                        1 août 2019 à 2:23:58

                        n'aurais tu pas commis la bêtise d'utiliser la directive using namespace std;?

                        Si tu regarde bien le code que je te donne (et pour lequel je suis sur qu'il fonctionne), tu remarquera que cette directive en est absente. Ce n'est pas pour rien, et tu viens sans doute de faire les frais d'un des innombrables problèmes qu'elle pose car il existe une fonction 

                        template <typename Iterator>
                        size_t std::distance(Iterator& a, Iterator &b);

                        qui permet de calculer le nombre d'éléments qui séparent deux éléments dans une collection (tableau, liste ou autre).  Cette directive a pour effet indirect que... c'est cette fonction (et non ta fonction distance) qui est prise en compte en priorité :p ;)

                        -
                        Edité par koala01 1 août 2019 à 2:35:32

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                          1 août 2019 à 2:51:57

                          ah oui : problème résolu ; merci beaucoup mon frere !
                          • Partager sur Facebook
                          • Partager sur Twitter

                          appel d'une fonction externe

                          × 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