C++ : Héritage, private, protected
Répondre à la discussion
Affichage des résultats 1 à 26 sur 26

C++ : Héritage, private, protected



  1. #1
    invite5e34a2b4

    C++ : Héritage, private, protected


    ------

    Bonjour à tous,
    Il y a quelque chose que je ne comprends pas très bien dans l'héritage.
    Si j'ai bien compris, l'intérêt de l'héritage est de ne pas avoir à réécrire des choses. Si une classe B hérite d'une classe A, elle contient les mêmes membres publics que A.
    Si je fais des modifications dans B, ça ne modifie rien dans A.
    Du coup, j'arrive pas à comprendre la raison qui a poussé les créateurs de C++ à rendre les membres privés de A absents de chez B. Est-ce que vous auriez un exemple qui pourrait montrer l'intérêt de faire ça ?
    Merci d'avance !

    -----

  2. #2
    Jack
    Modérateur

    Re : C++ : Héritage, private, protected

    si tu as besoin d'écrire une classe B spécialisant la classe A par héritage, afin de garantir un comportement correct des objets de la classe A, ses concepteurs se sont arrangés pour que tu ne puisses pas modifier certains de ses membres voire même ne surtout pas faire appel à ceux-ci, au cas où le fonctionnement interne de la classe A soit redéfini.

    Un exemple simple. La classe A est une classe Point qui décrit des points. A l'origine, le programmeur a prévu deux membres x et y pour stocker ses coordonnées. Si ces membres sont publiques, tu peux dériver la classe point pour créer une classe PointGraphique et tu vas te servir allègrement de x et y pour tes fonctions.

    Le créateur de la classe Point décide un jour que stocker les coordonnées sous forme polaire, c'est mieux: donc module et argument.
    Conséquence, tu n'as plus qu'à jeter ta classe PointGraphique à la poubelle.

    A+

  3. #3
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    Bonjour, voici un exemple:

    Code:
    class A
    {
    private:
      int jour;
    public:
      int getJour()
      {
        return jour;
      }
      void setJour(int valeur)
      {
        if (valeur > 0 && valeur < 32) jour = valeur; else jour = -1;
      }
    };
    La classe A a comme membre jour qui représente le jour du mois (entre 1 et 31) Si ce membre était public il serait possible de l'initialiser avec des valeurs invalides.

  4. #4
    invite5e34a2b4

    Re : C++ : Héritage, private, protected

    Je comprends pas très bien en fait.

    J'ai (pour reprendre un peu ton exemple) :

    Code:
    class point 
    {
    public: 
       point (int , int);   // constructeur qui donne les points par exemple
     
       void  affiche ();    // pour afficher 
    private:
       int  x;
       int  y;
    };
    
    class point3D : public point
    {
    public:
       point3D (int , int , int);
    private:
       int  z;
    };

    Soient p une classe point, p3D une classe point3D.
    Si je fais p.affiche, j'affiche les coordonnées (x,y) de p.
    Si je fais p3D.affiche, j'affiche les coordonnées (x,y) de p3D.

    p et p3D sont indépendants. Depuis p3D, je ne peux pas accéder aux membres x et y de p, même s'ils étaient publics.

    Du coup, je comprends pas la raison qui a poussé les créateurs de C++ à ne pas pouvoir manipuler directement x et y dans la classe point3D s'ils sont private dans la classe point.

    Si je suis pas très clair, faites savoir :$.

  5. A voir en vidéo sur Futura
  6. #5
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    Bonjour, ça n'a pas de sens de faire hériter point3D d'un point 2D. C'est le contraire un point 2D c'est un point 3D avec Z constant. Jack a expliqué que si tu modifies la représentation interne d'un point en passant de (x,y) à (angle et distance par rapport à l'origine) tu fais exploser toutes les classes dérivées qui utilisaient (x,y).

    Héritage : un point 2D est un point 3D (avec Z constant)

    Inclusion (j'ai oublié le terme exact) : un point 3D a un point 2D (en fait il peut être défini avec 2 points 2D mais c'est inutile).

  7. #6
    invite5e34a2b4

    Re : C++ : Héritage, private, protected

    Citation Envoyé par Zartan Voir le message
    Bonjour, ça n'a pas de sens de faire hériter point3D d'un point 2D. C'est le contraire un point 2D c'est un point 3D avec Z constant. Jack a expliqué que si tu modifies la représentation interne d'un point en passant de (x,y) à (angle et distance par rapport à l'origine) tu fais exploser toutes les classes dérivées qui utilisaient (x,y).

    Héritage : un point 2D est un point 3D (avec Z constant)

    Inclusion (j'ai oublié le terme exact) : un point 3D a un point 2D (en fait il peut être défini avec 2 points 2D mais c'est inutile).
    Bonjour Zartan,
    Tu es vraiment sûr de ce que tu dis ? Puisque si c'est ça, j'ai rien compris à l'héritage alors :s.
    Pour moi, un point 3D est un point 2D avec une 3ème coordonnée, la cote. Un point 3D contient toutes les propriétés du point 2D + une propriété supplémentaire. Il peut donc hériter de toutes les propriétés du point 2D.

    Sinon, vous entendez quoi par "modifier la représentation interne d'un point en passant à la représentation polaire" ?

  8. #7
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    L'héritage c'est une <classe fille> est <une classe mère>.

    Une voiture est un véhicule par conséquent la classe voiture héritera de véhicule.

    A partir d'un point 3D (x,y,z) je peux trouver les points (x,y) (x,z) et (y,x). Par conséquent lequel des 3 est le point 2D dont tu me parles ?

    On peut définir un point par ses coordonnées polaires : http://fr.wikipedia.org/wiki/Coordonnées_polaires

  9. #8
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    Pour essayer de mieux expliquer c'est comme si tu me disais qu'une ellipse est un cercle alors qu'un cercle est une ellipse.

    Techniquement, rien ne t'empêche de faire hériter une classe ellipse d'une classe cercle mais le résultat sera beaucoup plus compliqué que si tu fais hériter cercle de ellipse.

  10. #9
    invite5e34a2b4

    Re : C++ : Héritage, private, protected

    Citation Envoyé par Zartan Voir le message
    L'héritage c'est une <classe fille> est <une classe mère>.

    Une voiture est un véhicule par conséquent la classe voiture héritera de véhicule.

    A partir d'un point 3D (x,y,z) je peux trouver les points (x,y) (x,z) et (y,x). Par conséquent lequel des 3 est le point 2D dont tu me parles ?

    On peut définir un point par ses coordonnées polaires : http://fr.wikipedia.org/wiki/Coordonnées_polaires
    Il est question de codage là, pas de la vie de tous les jours. Evidemment qu'un point 3D n'est pas un point 2D au sens propre du terme.
    Mais de la même façon qu'une voiture est "un véhicule + autres choses", un point 3D est "un point 2D + autre chose (une 3e coordonnée)"...

    Je comprends pas l'intérêt de faire hériter d'une classe si c'est pour rendre inutile certains paramètres de la classe mère.

    Est-ce que je me trompe ?

  11. #10
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    On va du général au particulier, c'est plus simple comme ça

  12. #11
    invite5e34a2b4

    Re : C++ : Héritage, private, protected

    Nan, mais explique moi pourquoi c'est pas bien de faire hériter la classe point3D de la classe point2D.
    Et en termes de codage, pas de raisonnement sur les mots.
    Les exemples de voiture et de véhicule sont bien pour des exemples justement. Après quand on a des choses à coder, il faut pas rester dessus.
    Merci par avance.

  13. #12
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    Citation Envoyé par justine&coria Voir le message
    Je comprends pas l'intérêt de faire hériter d'une classe si c'est pour rendre inutile certains paramètres de la classe mère.

    Est-ce que je me trompe ?
    C'est une facilité d'écriture. Dans un cas l'héritage est facultatif et pas dans l'autre.

    Le design est correct si l'on peut modifier la représentation interne de la classe mère sans avoir à modifier les classes filles en quoi que ce soit.

  14. #13
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    Citation Envoyé par justine&coria Voir le message
    Nan, mais explique moi pourquoi c'est pas bien de faire hériter la classe point3D de la classe point2D.
    Et en termes de codage, pas de raisonnement sur les mots.
    Les exemples de voiture et de véhicule sont bien pour des exemples justement. Après quand on a des choses à coder, il faut pas rester dessus.
    Merci par avance.
    Code:
    class Point3D
    {
    private:
    	int _x;
    	int _y;
    	int _z;
    public:
    
    	int x()
    	{
    		return _x ;
    	}
    	int y()
    	{
    		return _y ;
    	}
    	int z()
    	{
    		return _z ;
    	}
    
    	Point3D(int x, int y, int z) : _x(x), _y(y), _z(z)
    	{}
    	void deplace(int dx, int dy, int dz)
    	{
    		_x += dx;
    		_y += dy ;
    		_z += dz ;
    	}
    	virtual void affiche()
    	{
    		cout << "(" << x() <<  ", " << y() << ", " << z() << ")" << endl ;
    	}
    };
    
    class Point2D : Point3D
    {
    public:
    	Point2D(int x, int y) : Point3D(x, y, 0)
    	{
    	}
    	void deplace(int dx, int dy) 
    	{
    		Point3D::deplace(dx, dy, 0) ;
    	}
    	void affiche()
    	{
    		cout << "(" << x() << ", " << y() << ")" ;
    	}
    };
    Voilà mes 2 classes, maintenant écris les tiennes à ta manière et demande toi ce qui se passe si on te demande de changer les coordonnées _x,_y et _z en float.
    En ce qui me concerne je n'ai rien à changer à Point2D.

    Code:
    class Point3D
    {
    private:
    	float _x;
    	float _y;
    	float _z;
    public:
    
    	int x()
    	{
    		return (int)_x ;
    	}
    	int y()
    	{
    		return (int)_y ;
    	}
    	int z()
    	{
    		return (int)_z ;
    	}
    
    	Point3D(int x, int y, int z) : _x(x), _y(y), _z(z)
    	{}
    	Point3D(float x,float y, float z) : _x(x), _y(y), _z(z)
    	{}
    	void deplace(int dx, int dy, int dz)
    	{
    		_x += dx;
    		_y += dy ;
    		_z += dz ;
    	}
    	virtual void affiche()
    	{
    		cout << "(" << x() <<  ", " << y() << ", " << z() << ")" << endl ;
    	}
    };
    Et toi ?

  15. #14
    Jack
    Modérateur

    Re : C++ : Héritage, private, protected

    j'arrive peut-être un peu tard mais, justine&coria, il me semble que l'exemple sur le changement de système de coordonnées démontrait l'intérêt de masquer les détails d'implémentation de la classe. Comment feras-tu si dans ton programme ou ta classe tu manipules les membres x et y et qu'un jour, ces membres viennent à disparaitre de la classe d'origine?

    A+

  16. #15
    invite5e34a2b4

    Re : C++ : Héritage, private, protected

    Citation Envoyé par Jack Voir le message
    j'arrive peut-être un peu tard mais, justine&coria, il me semble que l'exemple sur le changement de système de coordonnées démontrait l'intérêt de masquer les détails d'implémentation de la classe. Comment feras-tu si dans ton programme ou ta classe tu manipules les membres x et y et qu'un jour, ces membres viennent à disparaitre de la classe d'origine?

    A+
    Ok, je comprends. Merci beaucoup !

  17. #16
    invite5e34a2b4

    Re : C++ : Héritage, private, protected

    Citation Envoyé par Zartan Voir le message
    Code:
    class Point3D
    {
    private:
    	int _x;
    	int _y;
    	int _z;
    public:
    
    	int x()
    	{
    		return _x ;
    	}
    	int y()
    	{
    		return _y ;
    	}
    	int z()
    	{
    		return _z ;
    	}
    
    	Point3D(int x, int y, int z) : _x(x), _y(y), _z(z)
    	{}
    	void deplace(int dx, int dy, int dz)
    	{
    		_x += dx;
    		_y += dy ;
    		_z += dz ;
    	}
    	virtual void affiche()
    	{
    		cout << "(" << x() <<  ", " << y() << ", " << z() << ")" << endl ;
    	}
    };
    
    class Point2D : Point3D
    {
    public:
    	Point2D(int x, int y) : Point3D(x, y, 0)
    	{
    	}
    	void deplace(int dx, int dy) 
    	{
    		Point3D::deplace(dx, dy, 0) ;
    	}
    	void affiche()
    	{
    		cout << "(" << x() << ", " << y() << ")" ;
    	}
    };
    Voilà mes 2 classes, maintenant écris les tiennes à ta manière et demande toi ce qui se passe si on te demande de changer les coordonnées _x,_y et _z en float.
    En ce qui me concerne je n'ai rien à changer à Point2D.

    Code:
    class Point3D
    {
    private:
    	float _x;
    	float _y;
    	float _z;
    public:
    
    	int x()
    	{
    		return (int)_x ;
    	}
    	int y()
    	{
    		return (int)_y ;
    	}
    	int z()
    	{
    		return (int)_z ;
    	}
    
    	Point3D(int x, int y, int z) : _x(x), _y(y), _z(z)
    	{}
    	Point3D(float x,float y, float z) : _x(x), _y(y), _z(z)
    	{}
    	void deplace(int dx, int dy, int dz)
    	{
    		_x += dx;
    		_y += dy ;
    		_z += dz ;
    	}
    	virtual void affiche()
    	{
    		cout << "(" << x() <<  ", " << y() << ", " << z() << ")" << endl ;
    	}
    };
    Et toi ?
    Je suis pas convaincu pour plusieurs raisons :
    1. La classe Point2D prend plus de place que nécessaire sur le disque.
    2. La classe Point2D ne peut toujours pas avoir de coordonnées réelles.
    3. Si t'as rajouté un constructeur à Point3D, c'est parce que t'es au courant de Point2D, donc autant faire la modif dans Point2D aussi.

    Et enfin, pour reprendre ton exemple avec le véhicule et la voiture. Pourquoi ne pas faire de voiture la classe mère et véhicule comme classe fille pour laquelle tu mets à 0 tous les paramètres qui n'interviennent pas ? Puisque j'ai l'impression que c'est exactement ce que tu fais avec Point2D et Point3D.

  18. #17
    invite7a96054d

    Re : C++ : Héritage, private, protected

    Ta question initiale était : mais pourquoi donc un private ?
    La réponse la plus simple est pour cacher ce que l'utilisateur final n'a pas besoin de voir : c'est l'encapsulation.

    Imagine que ton point2d soit défini dans une bibliothèque que tu ne peux modifier. Imagine que les attributs x et y soient publics et que tu les utilises.
    Imagine maintenant que l'éditeur de la bibliothèque modifie point2d : plus de x ni de y, les coordonnées sont stockées en polaire avec rho et theta !
    Tu dois modifier ton application profondément.
    Imagine maintenant que les attributs aient été en private, tu ne pouvais accéder à cette information que via des accesseurs : bingo ! tu n'as qu'à recompiler ton appli et ça fonctionne toujours
    C'est un cas de figure ...
    Une technique encore plus avancée consiste à vraiment tout cacher : on appelle ça l'idiome pimpl.
    Cette technique (ne montrer que le strict nécessaire) n'est pas réservée au c++ (c++ permet de l'implémenter avec les modificateurs d'accès) et est mise en pratique dans toutes les implémentations de bibliothèques pour minimiser l'impact des modifications internes.

  19. #18
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    Citation Envoyé par justine&coria Voir le message
    Je suis pas convaincu pour plusieurs raisons :
    1. La classe Point2D prend plus de place que nécessaire sur le disque.
    2. La classe Point2D ne peut toujours pas avoir de coordonnées réelles.
    3. Si t'as rajouté un constructeur à Point3D, c'est parce que t'es au courant de Point2D, donc autant faire la modif dans Point2D aussi.

    1. J'ai bien dit que dans ce sens la classe était facultative.
    2. Quand le développeur de la classe Point2D est averti, il peut faire évoluer sa classe pour accepter les coordonnées réelles.
    3. Ca n'a rien à voir j'ai laissé l'ancien constructeur, car on ne modifie JAMAIS un membre public, sauf si on veut rendre la classe incompatible avec ses versions précédentes. Le nouveau constructeur n'est pas utilisé par Point2D mais le sera peut-être plus tard quand le développeur sera au courant de l'évolution.

    Et enfin, pour reprendre ton exemple avec le véhicule et la voiture. Pourquoi ne pas faire de voiture la classe mère et véhicule comme classe fille pour laquelle tu mets à 0 tous les paramètres qui n'interviennent pas ? Puisque j'ai l'impression que c'est exactement ce que tu fais avec Point2D et Point3D.
    Si voiture est la classe mère et véhicule la classe fille, comment envisages-tu une classe avion ou bateau ?

    La question à se poser est : "la classe mère est-elle une généralisation de la classe fille ?"

  20. #19
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    En fait, je comprends ton problème : pour toi un point 3D c'est un point 2D avec une coordonnée en plus.

    Ca marche bien pour par exemple Point2DEnCouleur qui est un point 2D avec une couleur en plus. On la fait hériter de Point2D sans problème. Un Point2DEnCouleur est un Point2D.

    Pour Point3D c'est plus délicat car un Point3D n'est pas un point 2D. On peut dire qu'il a un point 2D (xy) mais on peut dire qu'il a également les points 2D (y,z) et (x,z).

    héritage 2D -> 3D:
    Un point 3D a(x,y,z) n'est pas le point 2D a'(x,y)
    Exemple: si le point3D a(2,3,4) est le point2D a'(2,3) et que le point3D b(2,3,5) est le point b'(2,3) alors a = b ce qui est faux.

    héritage 3D->2D
    Quelque soit le point 2D a(x,y) ce point est le point 3D a'(x,y,0)



    Toutefois j'ai déjà dit que ça pouvait marcher techniquement (ça compile) , c'est juste beaucoup plus compliqué, d'ailleurs on remarque que dans les implémentations courantes les deux classes sont complètement séparées.

  21. #20
    invite5e34a2b4

    Re : C++ : Héritage, private, protected

    Tu tiens beaucoup à cette interprétation logique, qui pour moi n'est qu'un moyen de se rappeler ce que sont vraiment les classes mères et filles. Je pense pas qu'il faille être aussi rigide.
    Puisque si on veut jouer avec les mots, tu dis que "Quelque soit le point 2D a(x,y) ce point est le point 3D a'(x,y,0)" : pourquoi pas le point a'(x,y,1) ou a"(x,y,3829,28202) ?

    En plus, dans ton exemple, tu choisis des points particuliers, comme si un point (2,3,5) était créé à partir du point (2,3). Ce n'est pas vrai. Un point2D est une collection de 2 nombres, un point3D une collection de 3 nombres. Lorsque je créé une classe point3D avec (2,3,5) pour coordonnées, aucune classe point2D avec (2,3) pour coordonnées n'est créé.
    C'est exactement comme rajouter une couleur à ton point, si ce n'est que c'est une troisième coordonnée.

  22. #21
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    Citation Envoyé par justine&coria Voir le message
    Tu tiens beaucoup à cette interprétation logique, qui pour moi n'est qu'un moyen de se rappeler ce que sont vraiment les classes mères et filles. Je pense pas qu'il faille être aussi rigide.
    Ca n'a rien de rigide. Ce n'est pas avantageux de créer un point 3D à partir d'un point 2D.

    Puisque si on veut jouer avec les mots, tu dis que "Quelque soit le point 2D a(x,y) ce point est le point 3D a'(x,y,0)" : pourquoi pas le point a'(x,y,1) ou a"(x,y,3829,28202) ?
    A partir du moment où Z est constant on peut le dire en effet. Mais si tu choisis 3829,28202 tu devras le garder pendant tout le programme.


    En plus, dans ton exemple, tu choisis des points particuliers, comme si un point (2,3,5) était créé à partir du point (2,3). Ce n'est pas vrai. Un point2D est une collection de 2 nombres, un point3D une collection de 3 nombres. Lorsque je créé une classe point3D avec (2,3,5) pour coordonnées, aucune classe point2D avec (2,3) pour coordonnées n'est créé.
    Le Point (2,3) est le point (2,3,0), c'est à dire que je peux utiliser n'importe quel membre 3D, par exemple le déplacer.

    C'est exactement comme rajouter une couleur à ton point, si ce n'est que c'est une troisième coordonnée.
    Non ce n'est pas pareil parce que pour un Point2DEnCouleur le membre deplacer(x, y) est celui de la classe mère alors que dans l'autre sens il faut réécrire tous les membres.

    Si tu veux créer un point3D à partir d'un point2D tu dois utiliser la relation : un point 3D contient un point 2D

    Code:
    class Point3D 
    {
    private:
        Point2D point2D; //  x et y
        int z;  //  z
       ...
    De toutes manières tu devras réécrire chaque membre, alors l'héritage n'a aucun intérêt ici.

  23. #22
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    Si ça t'intéresse d'approfondir le sujet je te recommande ce livre : http://www.editions-eyrolles.com/Liv...rientees-objet

    Tu as même quelques chapitres en téléchargement dont celui-ci : http://www.editions-eyrolles.com/Cha...ap24_Meyer.pdf

  24. #23
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    Citation Envoyé par Zartan Voir le message
    Le Point (2,3) est le point (2,3,0), c'est à dire que je peux utiliser n'importe quel membre 3D, par exemple le déplacer.
    J'ai été un peu approximatif ici, en fait la fonction déplacer va poser un gros problème. Le polymorphisme ne fonctionne pas très bien de 3D vers 2D, ni de 2D vers 3D d'ailleurs c'est pour cette raison que ces deux classes ne sont pas les meilleurs choix pour parler d'héritage.

  25. #24
    invite5e34a2b4

    Re : C++ : Héritage, private, protected

    Merci Zartan, je comprends bien mieux maintenant. Merci beaucoup !!
    Au vu de ce qu'on vient de dire, est-ce que l'héritage a un intérêt bien particulier en fait ? J'ai la sensation qu'il s'agit simplement de ne pas avoir à réécrire certaines choses.

  26. #25
    invited1c1a33e

    Re : C++ : Héritage, private, protected

    En général on veut faire hériter pour ne pas avoir à réécrire les mêmes fonctions. Et ça sert également dans le polymorphisme.

    Si tu as une classe Vehicule, tu peux avoir une classe Voiture et une classe Bateau que tu vas manier comme des véhicules sans te préoccuper de ce qu'ils sont.


    Code:
        Vehicule* tableauVehicules[2] ;
        tableauVehicule[0] = new Bateau() ;
        tableauVehicule[1] new Voiture() ;
    
        for (int i=0; i<2; i++)
        {
              tableauVehicule[i]->repeindre(ROUGE) ; // polymorphisme
        }

  27. #26
    Jack
    Modérateur

    Re : C++ : Héritage, private, protected

    J'ai la sensation qu'il s'agit simplement de ne pas avoir à réécrire certaines choses.
    C'est en effet un aspect intéressant, ça évite d'avoir à réinventer quelque chose d'existant, testé et optimisé alors que n'a besoin que de rajouter un ou deux services à ceux de la classe d'origine.

    Pour constater les avantages de l'héritage ou autres aspects du C++, le mieux est de voir ce qui existe. Regarde la bibliothèque de Qt et tu constateras l’utilisation massive de l'héritage:
    http://doc.qt.digia.com/4.7/classes.html

    A+

Discussions similaires

  1. Héritage
    Par invitecc87dbce dans le forum Programmation et langages, Algorithmique
    Réponses: 0
    Dernier message: 27/05/2012, 20h32
  2. recherche équivalent gratuit de private exe protector
    Par invitea06ec63e dans le forum Logiciel - Software - Open Source
    Réponses: 7
    Dernier message: 31/01/2010, 14h21
  3. aide batch fichier private
    Par invite6bd30976 dans le forum Logiciel - Software - Open Source
    Réponses: 1
    Dernier message: 16/01/2010, 07h44
  4. private joke ....
    Par invitebe0cd90e dans le forum Science ludique : la science en s'amusant
    Réponses: 0
    Dernier message: 15/01/2005, 00h13