Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème héritage avec include !

Sujet résolu
    23 juin 2018 à 21:43:01

    Bonjour j'aimerais savoir dans le main si l'on dois inclure seulement la class mère pour que les héritages fonctionne type : #include "mere.h" ou plutôt inclure toutes nos class type : #include "mere.h" #include "fille1.h" #include "fille2.h" ?

    Merci  de vos réponses !

    • Partager sur Facebook
    • Partager sur Twitter
      23 juin 2018 à 21:57:26

      Ca dépend de ce que le code fait dans le main.

      S'il  fait référence à une classe fille, c'est mieux qu'il inclue le fichier d'entete correspondant.

      Pour une réponse précise, donne un exemple précis....

      -
      Edité par michelbillaud 23 juin 2018 à 21:58:05

      • Partager sur Facebook
      • Partager sur Twitter
        23 juin 2018 à 22:02:05

        MAIN:

        #include <iostream>
        #include "souris.h"
        
        using namespace std;
        
        int main()
        {
            s_gaming asus(5,8000);
            asus.dscpt();
        
            s_bureau logitec(3, 1000);
            logitec.dscpt();
        
            return 0;
        }
        

        ERREUR:

        ||=== Build: Debug in Evolution++ (compiler: GNU GCC Compiler) ===|

        C:\Users\mathi\Desktop\c++\Evolution++\main.cpp||In function 'int main()':|

        C:\Users\mathi\Desktop\c++\Evolution++\main.cpp|8|error: 's_gaming' was not declared in this scope|

        C:\Users\mathi\Desktop\c++\Evolution++\main.cpp|9|error: 'asus' was not declared in this scope|

        C:\Users\mathi\Desktop\c++\Evolution++\main.cpp|11|error: 's_bureau' was not declared in this scope|

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

        CLASS:

        Class mère : souris

        Cette class a deux filles : s_gaming (pour souris gaming) et s_bureau (pour souris de bureau)

        -
        Edité par JeanPolo1 23 juin 2018 à 22:05:00

        • Partager sur Facebook
        • Partager sur Twitter
          23 juin 2018 à 22:05:57

          Tu as la réponse à ta question.

          •  's_gaming' was not declared in this scope

          •  's_bureau' was not declared in this scope

          va falloir les déclarer avant des utiliser, et les déclarations sont dans ...... ?

          -
          Edité par michelbillaud 23 juin 2018 à 22:06:28

          • Partager sur Facebook
          • Partager sur Twitter
            23 juin 2018 à 22:11:09

            Class fille s_gaming :

            #ifndef S_GAMING_H_INCLUDED
            #define S_GAMING_H_INCLUDED
            #include "souris.h"
            
            class s_gaming: public souris
            {
            public:
                void dscpt();
            };
            
            #endif // S_GAMING_H_INCLUDED
            


            Encore une question: 
            Somment nous obliger de faire un constructeur pour chaque class fille ou la class fille herite automatiquement du constructeur de la class mere ?

            (Je découvre la POO car avant je faisais du C ..)

            -
            Edité par JeanPolo1 23 juin 2018 à 22:14:57

            • Partager sur Facebook
            • Partager sur Twitter
              24 juin 2018 à 12:19:40

              On n'hérite pas des constructeurs.

              Si la classe B dérive de la classe A, un constructeur de A est appelé pendant la construction de B, que ça soit explicite ou pas.

              Pour arriver à t'y retrouver, je te suggère très fortement d'écrire toi-même des tests de quelques lignespour voir ce qui se passe et contrôler que tu as bien compris. Comme celui-ci par exemple

              #include <iostream>
              
              class A {
                public:
                  A() {
                    std::cout << "le constructeur A() est appelé" << std::endl;
                }
              };
              
              class B : public A {
                public:
                B() {
                     std::cout << "le constructeur B() est appelé" << std::endl;
                }
              };
              
              int main()
              {
              	B b;
              	return 0;
              }
              
              • A ton avis, il affiche quoi ?
              • si tu enlèves la définition du constructeur de B, il se passera quoi ?

              -
              Edité par michelbillaud 24 juin 2018 à 12:21:25

              • Partager sur Facebook
              • Partager sur Twitter
                24 juin 2018 à 15:21:01

                Et, surtout, l'héritage public est la relation la plus forte qui puisse exister entre deux classe, car il représente une relation EST-UN (une maison EST-UN bâtiment, une voiture EST-UN véhicule, un chat EST-UN animal, ...).

                En quoi  un s_gaming -- quoi que ce puisse être -- pourrait-il être une souris?

                CE N'EST PAS parce que deux classes exposent des services similaires (getX(), getY(), moveTo(...) ) que tu peux décider de faire hériter l'une de l'autre!

                Pour que tu puisse décider de faire hériter s_gaming de souris,  tu dois avoir la certitude que tu puisse passer un élément de type s_gaming à n'importe quelle fonction qui s'attend à recevoir un élément de type souris comme paramètre et que la fonction (ainsi que le paramètre) réagiront de la manière adéquate.

                Une souris, c'est un "truc" que tu peux déplacer, avec plusieurs boutons sur lesquels tu peux appuyer, soit pour faire un "clique", soit pour faire un "drag and drop".  S'il n'y a qu'une seule de ces caractéristiques qui est absente de s_gaming, tu ne peux pas faire hériter s_gaming de souris.

                Par contre, tu peux t'intéresser aux comportements qui permettent:

                • de définir la position initiale d'un élément (fixe)
                • de demander à un élément de se déplacer
                • de demander à un élément d'émettre un signal quand on a cliqué dessus
                • de demander à un élément d'émettre un signal au début du drag et à la fin du dorp

                Et comme tous ces comportements nécessitent la possibilité de ... définir la position initiale de l'élément, tu peux envisager de créer une hiérarchie d'héritage (qui sera considérée comme une interface) qui regroupera le tout sous une forme proche de

                class Positionable{
                public:
                    Positionable(Positionable const &) =delete;
                    Positionable & operator=(Positionable const &) = delete;
                    int x() const{return x_;}
                    int y() const{return y_;}
                protected:
                    Positionnable(int x, int y):x_{x}, y_{y}{}
                    ~Positionnable()= default;
                    void setX(int x){x_=x;}
                    void setY(int y){y_=y;}
                private:
                    int x_;
                    int y_;
                };
                class Movable : public Positionnable{
                public:
                    void moveTo(int x, int y){
                        setX(x);
                        setY(y);
                    }
                protected:
                    Movable(int x, int y): Positionnable{x,y}{}
                };
                class Clickable : public Movable(){
                public:
                    using click_slot = typename Signal<int, int>::slot_type;
                    Connection onClick(click_slot slot){
                        return clickSig_.connect(slot);
                    }
                    void click(){
                        clickSig_(x(), y());
                    }
                protected:
                    Clickable(int x, int y): Movable{x, y}{}
                private:
                    Signal<int, int> clickSig_;
                };
                class DragDrogable: public Clickable{
                public:
                    enum DragState{
                        begin,
                        end
                    };
                    using grag_slot = typename  Signal<DragState, int, int>::slot_type;
                    
                    Connection onDragBegin(click_slot slot){
                        return dragBegin_.connect(slot);
                    }
                    Connection onDragEng(click_slot slot){
                        return dragEnd_.connect(slot);
                    }
                    void dragBegin(){
                        dragBegin_(begin,x(), y());
                    }
                    void dragEnd(){
                        dragEnd_(end,x(), y());
                    }
                protected:
                    DragDrogable(int x, int y):Clickable{x, y}{}
                private:
                    Signal<DragState, int, int> dragBegin_;
                    Signal<DragState, int, int> dragEnd_;
                };

                Et si ta souris permet le drag and drop, tu pourras la faire hériter de ...DragDrogable.  Par contre, si ton s_gaming peut -- au mieux (*)-- indiquer sa position, tu pourra le faire hériter de ... Positionnable.

                (*)Et encore, comme je n'ai aucune idée de ce que cela représente, je serais étonné que l'on attende de lui qu'il puisse donner sa position  ;)

                • 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

                Problème héritage avec include !

                × 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