IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Passer de la composition à l'héritage


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2015
    Messages : 14
    Par défaut Passer de la composition à l'héritage
    Bonjour, pour un travail, je dois faire un programme avec les classes point, carré et cube. Je dois faire un programme utilisant la composition et un programme avec l'héritage.
    J'ai terminé la partie composition mais j'ai de la difficulté à transférer vers l'héritage. Il est difficile pour moi de faire le lien entre les classes.

    Merci beaucoup! N'hésitez pas si vous avez des questions.

    Voici la partie composition:

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    #include <iostream>
    #include <math.h>
     
    using namespace std;
     
    class Point {
        public: //declarer la fonction set_values
            void set_values (int x, int y){ //Les coordonnees des points sont des int
                this->x=x; this->y=y;
            }
            int getX(){return this->x;} //pointers vers les valeurs
            int getY(){return this->y;}
        private:
            int x,y; //les coordonnes sont des int
    };
     
    class Carre {
        public:
            void set_points(Point p1, Point p2) //La fonction qui set les 2 points du carres, car un carre peut se faire a partir de 2 pts
            {
                this->p1 = p1;
                this->p2 = p2;
            }
            float length(){return  sqrt(((p2.getY() - p1.getY()) * (p2.getY() - p1.getY())) + ((p2.getX() - p1.getX()) * (p2.getX() - p1.getX())));} //Derive du theoreme de Pythagore pour trouver la distance entre 2 pts
     
            float aire() //Utilisation de float pour la precision avec les racines carres
            {return  length() * length();} //Le cote multiplier par lui-meme donne l'aire
        private:
            Point p1,p2;
    };
     
    class Cube{
        public:
            void set_carre(Carre carre){this->carre = carre;}
            float volume()
            {return  carre.aire() * carre.length();} //Le volume est length au cube ou aire*length
        private:
            Carre carre;
    };
     
    int main()
    {
     
     cout << "***** Point, carre et cube en heritage *****" << endl;
     cout << endl;
     
    int a,b,c,d; //L'utilisateur entre les coordonnes
     cout <<"Coordonner en X du premier point: "; cin>>a;
     cout <<"Coordonner en Y du premier point: "; cin>>b;
     cout <<"Coordonner en X du deuxieme point: "; cin>>c;
     cout <<"Coordonner en Y du deuxieme point: "; cin>>d;
     
     Point p1,p2;
     Carre carre1;
     Cube cube1;
     
     p1.set_values(a,b); //Les valeurs sont mis pour les points, le carre et le cube
     p2.set_values(c,d);
     carre1.set_points(p1,p2);
     cube1.set_carre(carre1);
     
     cout << endl;
     cout <<"********************************************" << endl;
     //cout  le resultat
     cout << "L'aire du carre est de " <<carre1.aire() << endl;
     cout << "Le volume du cube est de "<<cube1.volume() << endl;
     
    return 0;
     
    }



    Et voici ou j'en suis avec l'héritage:

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    #include <iostream>
    #include <math.h>
     
    using namespace std;
     
    class Point {
        public:
            void set_values (int x, int y){
                this->x=x; this->y=y;
            }
            int getX(){return this->x;}
            int getY(){return this->y;}
        private:
            int x,y;
    };
     
    class Figure {
        private:
            Point[] points = {point1,point2,point3,point4};
        public:
            figure(4){points = Point[nbPoints];}
            void set_points(Point[] points){this->points = points;}
     
            void longueur()
            {return point4.x-point1.x;}
     
            void largeur()
            {return point2.y-point1.y;}
     
    };
     
    class Carre: public Figure {
     
        private:
     
        public:
            void aire()
            {return longueur()*largeur();}
     
    };
     
    class Cube: public Carre {
        private:
     
        public:
            void volume()
            {return aire()*longueur();}
    };
     
    int main()
    {
        Point point1,point2,point3,point4;
        point1.set_values(0,0)
        point2.set_values(0,5)
        point3.set_values(5,5)
        point4.set_values(5,0)
     
    }

  2. #2
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par défaut
    Et si pour ton héritage tu voyais un cube comme une figure de 8 points, un carré est une figure de 4 points.
    Figure pourrais avoir un nombre parametrable de points defini par une position, une largeur, une hauteur et une profondeur.

  3. #3
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Remarque sur ta définition d'un carré à partir de deux points :
    A partir de ta formule de Carre::length(), on peut en déduire que tu définis un carré à partir de deux points consécutifs dans ce carré (nommons-les A et B). Dans le plan, le point suivant, C, a deux positions possibles mais ton code actuel ne permet pas de savoir laquelle : l'angle ABC, fait-il +90° ou bien -90° ?
    Par exemple, si A=(0,0) et B=(1,0), est-ce que C=(1,1) ou bien C=(1,-1) ?
    Dans l'espace, c'est pire : le point C a une infinité de positions possibles.

    Dans l'espace, le même problème se pose avec ton cube défini à partir d'un carré.
    Par exemple, à partir d'un carré (A,B,C,D) avec A=(0,0,0), B=(1,0,0), C=(1,1,0) et D=(1,1,0), est-ce que les 4 autres points de ton cube ont pour 3e coordonnée 1 ou bien -1 ?

    Dans le cas de l'héritage :
    • Cube ne doit pas dériver de Carre. Ça n'a pas de sens de pouvoir faire monCube.aire().
    • Si Cube et Carre dérivent publiquement de Figure et que, plus tard, Figure pourra avoir d'autres classes dérivées comme Ellipse, Pyramide, etc, la question que tu dois te poser est : quelles sont les fonctions qui peuvent avoir un sens pour n'importe quelle figure ? Seules ces fonctions pourront être présentes dans la classe Figure.

  4. #4
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2015
    Messages : 14
    Par défaut
    Notre enseignant nous a dit que l'exercice n'était pas idéal puisqu'il y a quelques imprecisions mathématiques. Ma structure est 'bonne', je dois maintenant terminer le code en lien avec celui déja fait (voir composition).

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Tu pourras même frapper très fort ton prof, car l'exercice est purement et simplement conceptuellement faux:
    1. un carré ne peut pas dériver d'un rectangle (la précondition longueur == largeur dans le carré est plus forte que celle (inexistante) dans le rectangle)
    2. un carré (respectivement un cube) n'est jamais qu'un "état particulier" du rectangle (respectivement du parallélipipède rectangle). L'idéal est "tout simplement" d'avoir une fonction isSquare (ou similaire) permettant de tester si cet état est atteint ou non
    3. Généralement, on fait au contraire tout notre possible pour éviter l'héritage : on essayera le plus souvent de passer de l'héritage à la composition. Je n'ai -- pour ma part -- jamais essayé de faire l'inverse
    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

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Ceci étant dit, quelques remarques d'ordre générale :
    1. Les setter, c'est mal (en vertu de la loi de Déméter)
    2. Si tu change une valeur (x ou y ) de ta classe point, tu obtiens forcément un point différent... Une fois qu'il a été créé (et parce qu'il a sémantique de valeur), le point devrait être constant
    3. Tu réfléchis beaucoup trop en terme de données manipulées par tes classes, alors que tu devrais réfléchir en termes de services proposés par celles-ci
    4. une ligne, une instruction s'il te plait : le compilateur s'en fout royalement du nombre de lignes de ton code, mais celui qui devra le relire s'y retrouvera beaucoup mieux ;-
    5. les accesseurs (getX et getY) devraient être des fonctions membres constantes
    6. this n'est pas nécessaire pour les accesseurs
    7. en donnant un nom différents au paramètres transmis à set_values, tu pourrais éviter l'utlisation de this dans cette fonction
    8. soit un peu cohérent dans la manière d'orthographier les différents éléments : tu as getX et getY d'un coté et ... set_values de l'autre... une petite harmonisation s'impose, vu que ce sont trois fonctions, et que la manière dont elle sont nommée devrait donc être identique
    9. ne prédéclare pas tes données : attends d'avoir "toutes les informations" nécessaires pour créer tes objets (principalement tes Carre, Cube et autres), et utilise le constructeur "qui va bien" de manière à ce que tu puisse directement les utiliser sans avoir à risquer d'oublier une action quelconque (défini ce constructeur en cas de besoin )
    10. ne jamais inclure tout l'espace de noms std : es tu si fainéant que cela pour ne pas vouloir ajouter std:: devant cout ou cin??? Au pire, inclus uniquement les éléments qui t'intéressent sous la forme de (par exemple) using std::cout;, using std::cin; ou using std::string; et quoi qu'il en soit, jamais dans un fichier d'en-tête ;p
    11. math.h, c'est le fichier d'en-tête de C... En C++, on utilise cmath
    12. Tu te fais beaucoup de mal pour calculer la taille du coté d'un carré en passant par pythagore : calcule "simplement" la différence absolue entre la coordonnée X (ou la coordonnée Y) des deux points, et vérifie (au niveau du constructeur) que tu obtiens bel et bien la même distance des deux cotés.
    13. Pour le volume d'un cube, pourquoi aire * lengt et pas quelque chose comme
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
       auto size = carre.length();  // pas besoin de la calculer trois fois, surtout que tu utilise pythagore !!!
      return size * size * size;
    14. length ne me semble pas le meilleur nom pour la fonction... size serait à mon sens bien mieux
    15. Si l'utilisateur crée un carré qui n'est pas carré, c'est une erreur de programmation : il faudrait une assertion lorsque l'on défini les points
    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

Discussions similaires

  1. Generics. Composition et héritage
    Par le Daoud dans le forum Langage
    Réponses: 3
    Dernier message: 22/07/2010, 09h21
  2. Design composite et héritage multiple
    Par Xanto dans le forum Langage
    Réponses: 4
    Dernier message: 29/05/2009, 19h54
  3. composition et héritage: problème d'énoncé?
    Par johnny3 dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 04/01/2009, 12h40
  4. Héritage de composition.
    Par 3DArchi dans le forum BOUML
    Réponses: 1
    Dernier message: 30/07/2008, 14h59
  5. Héritage VS Composition
    Par bolhrak dans le forum C++
    Réponses: 8
    Dernier message: 18/12/2006, 04h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo