Partage
  • Partager sur Facebook
  • Partager sur Twitter

Je ne comprends pas l'héritage en protected

    30 mars 2008 à 15:34:42

    Bonjour tout le monde,

    J'ai une classe de base que voici :

    1. class CPersonne
    2. {
    3. public:
    4.         CPersonne();
    5.         CPersonne(const char* Nom,const char* Prenom,int Age);
    6.         ~CPersonne();
    7.         bool                    Nom(const char* UnNom);
    8.         bool                    Prenom(const char* UnPrenom);
    9. protected:
    10.         bool                    Age(int UnAge);
    11. private:
    12.         double                  m_Sexe;
    13. };


    J'ai une classe dérivée qui va hériter d'une manière Protected à la classe de base :
    1. class CGarcon : protected CPersonne
    2. {
    3. };


    Dans le main, je fais ceci :

    1. CGarcon Eric;
    2. Eric.Age(3);


    à la compilation, j'ai ce message d'erreur :

    Citation : beegees

    error C2248: 'Age' : cannot access protected member declared in class 'CPersonne'



    Je ne comprends pas alors l'intérêt d'hériter de manière Protected d'une classe de base si on ne peut pas utiliser ces fonctions protégées.

    Sauriez-vous m'expliquer car je n'ai pas compris.

    Un super grand merci d'avance.

    beegees
    • Partager sur Facebook
    • Partager sur Twitter
      30 mars 2008 à 15:40:33

      Si si on peut, seulement tu as du oublié d'inclure un header ou un truc du genre. Car en gros private c'est uniquement pour ce qui est des methodes / propriétées internes au fonctionnement de la classe, protected c'est un peu pareil, mais ça peut être etendu aux classes filles, et public est accessible depuis n'importe quelle classe qui instancie ta classe. Et ajoutes un constructeur à CGarcon, concevoir une classe, meme héritée sans meme y intégrer un constructeur je ne l'ai jamais fait. Ne serais ce que pour appeller le constructeur de CPersonne.
      • Partager sur Facebook
      • Partager sur Twitter
        30 mars 2008 à 16:07:13

        Merci pour ta réponse.

        Quand tu dis :

        Citation : askerat

        private c'est uniquement pour ce qui est des methodes / propriétées internes au fonctionnement de la classe



        Quel est l'intérêt alors de mettre CGarcon : private CPersonne ???

        ça ne fonctionne toujours pas mais pourtant le header est inclus.

        Voici mon code :

        le header (.h) :

        1. class CPersonne;
        2. class CGarcon;
        3. class CPersonne
        4. {
        5. public:
        6.         CPersonne();
        7.         ~CPersonne();
        8.         void                    Nom(const char* UnNom);
        9.         bool                    Prenom(const char* UnPrenom);
        10. protected:
        11.         bool                    Age(int UnAge);
        12. private:
        13.         double                  m_Sexe;
        14. };
        15. class CGarcon : public CPersonne
        16. {
        17. public:
        18.         CGarcon();
        19.         ~CGarcon();
        20. };


        Voici le fichier .cpp qui contient les constructeurs et destructeurs :

        1. #include <BasicConsole.h>
        2. #include "test.h"
        3. CPersonne::CPersonne()
        4. {
        5. }
        6. CPersonne::~CPersonne()
        7. {
        8. }
        9. CGarcon::CGarcon()
        10. {
        11. }
        12. CGarcon::~CGarcon()
        13. {
        14. }
        15. CGarcon::Nom("Eric")
        16. {
        17. }


        Et voici mon main :

        #include <BasicConsole.h>
        #include "test.h"

        1. void main()
        2. {
        3.         CGarcon UnGars;
        4.         UnGars.Nom("Eric");
        5. }


        me donne :

        Citation : compilateur C++

        error C2248: 'Age' : cannot access protected member declared in class 'CPersonne'



        Merci encore pour ton aide.

        beegees
        • Partager sur Facebook
        • Partager sur Twitter
          30 mars 2008 à 16:14:44

          Essaye voir d'ajouter :

          CGarcon() : CPersonne();

          dans le .h et dans le .cpp pour appeller le constructeur de la classe mere. Normalement si tu le specifies pas il est appellé automatiquement ( du moins en java ), je me suis mis sur le C++ que récemment.
          • Partager sur Facebook
          • Partager sur Twitter
            30 mars 2008 à 16:32:15

            Citation : beegees

            Je ne comprends pas alors l'intérêt d'hériter de manière Protected d'une classe de base si on ne peut pas utiliser ces fonctions protégées.


            l'erreur (je pense) est que comme tu utilises un héritage protected, les fonctions public deviennent protected donc ceci n'est pas possible :
            1. CGarcon UnGars;
            2. UnGars.Nom("Eric"); // Nom() est protected
            • Partager sur Facebook
            • Partager sur Twitter
              30 mars 2008 à 18:50:48

              Citation : minirop

              Citation : beegees

              Je ne comprends pas alors l'intérêt d'hériter de manière Protected d'une classe de base si on ne peut pas utiliser ces fonctions protégées.


              l'erreur (je pense) est que comme tu utilises un héritage protected, les fonctions public deviennent protected donc ceci n'est pas possible :

              1. CGarcon UnGars;
              2. UnGars.Nom("Eric"); // Nom() est protected


              Merci Minirop pour ta réponse.

              Je pense que tu as raison quand tu dis que les fonctions publiques deviennt protected quand je j'hérite de façon protected.

              Mais alors à quoi ça sert de mettre protected et Private si on ne peut pas accèder à partir de la classe fille aux fonctions membres et variables ?

              Je ne comprends pas l'intérêt.

              J'espère que vous pourrez encore m'aider.

              Merci
              beegees
              • Partager sur Facebook
              • Partager sur Twitter
                30 mars 2008 à 18:58:15

                je crois qu'il faut heriter en public

                donc
                1. class CGarcon : protected CPersonne
                2. {
                3. };

                devien
                1. class CGarcon : public CPersonne
                2. {
                3. };
                • Partager sur Facebook
                • Partager sur Twitter
                  30 mars 2008 à 19:03:01

                  Merci pour ta réponse danman,

                  Si j'hérite en pubic, ça fonctionne.

                  Mais alors, je ne sais pas pourquoi on peut et on met le protected et le private comme dans l'exemple ci-dessous :

                  1. #ifndef CHAINE_H
                  2. #define CHAINE_H
                  3. class CChaine
                  4. {
                  5. public:
                  6.         CChaine();                                                                                                                              // Constructeur par défaut
                  7.         CChaine(const CChaine& Source);                                                                                 // Constructeur par copie
                  8.         CChaine(const char* UneChaine);                                                                                 // Constructeur spécifique
                  9.         ~CChaine();                                                                                                                             // Destructeur
                  10.         const char*             Chaine() const;                                                                                 // Accesseur du texte de la chaîne
                  11.         bool                    EstNull() const;                                                                                // Accesseur de test sur le texte (m_Chaine == NULL)
                  12.         bool                    EstVide() const;                                                                                // Accesseur de test sur le texte (m_Chaine == NULL) || (m_Chaine == "")
                  13.         void                    Vider();                                                                                                // Modificateur permettant de supprimer le texte de la chaîne (on revient à NULL)
                  14.         bool                    Chaine(const char* UneChaine);                                                  // Modificateur du texte de la chaîne
                  15. private:
                  16.         char*                   m_Chaine;                                                                                               // Membre contenant l'adresse du tableau de caractères alloué dynamiquement
                  17. };
                  18. class CChaineComposee : <couleur nom="rouge">private</couleur><gras/> CChaine
                  19. {
                  20. public:
                  21.         CChaineComposee();                                                                                                              // Constructeur par défaut
                  22.         CChaineComposee(const CChaineComposee& Source);                                                 // Constructeur par copie
                  23.         CChaineComposee(const char* UneChaine, char UnSeparateur);                              // Constructeur spécifique
                  24.         ~CChaineComposee();                                                                                                             // Destructeur
                  25.         long                    NombreChamps() const;                                                                   // Accesseur du nombre de champs
                  26.         const char*             Champs(long Indice) const;                                                              // Accesseur d'un champ
                  27.         bool                    Definir(const char* UneChaine, char UnSeparateur);              // Modificateur permettant de modifier la chaîne et de générer le tableau des champs
                  28. private:
                  29.         bool                    Decomposer(char UnSeparateur);                                                  // Modificateur permettant de modifier la chaîne et de générer le tableau des champs
                  30. private:
                  31.         long                    m_NbrChamps;
                  32.         char**                  m_Champs;
                  33. };
                  34. class CChargeurFichierTexte : public CChaineComposee
                  35. {
                  36. public:
                  37.         CChargeurFichierTexte();
                  38.         ~CChargeurFichierTexte();
                  39.         bool                    Charger(const char* NomFichier, char UnSeparateur, bool (* FctnTraiterLigne)(const CChargeurFichierTexte&, void*), void* Contexte);
                  40. private:
                  41. };
                  42. #endif//CHAINE_H


                  Merci pour la lumière que vous m'apporterez.

                  beegees
                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 mars 2008 à 20:02:35

                    Oublie l'héritage protégé, il y a quelques rares idiomes qui l'exploitent, mais en général on n'utilise que :
                    - l'héritage public quand on veut la substituabilité (et éventuellement importer du code)
                    - l'héritage privé quand on veut importer du code sans permettre la substituabilité.

                    Comprends la notion fondamentale de substituabilité, et tu auras compris l'héritage.
                    • Partager sur Facebook
                    • Partager sur Twitter
                    C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                    Anonyme
                      30 mars 2008 à 21:52:13

                      Pour simplifier le propos de lmghs (qui est à 100% correct) utilise l'héritage public quant ta classe dérivé peut remplacer l'objet de base et l'héritage privé quand ta classe dérivé exprime la relation "Est implémenté sous forme de".

                      Exemple :
                      Pour l'héritage public:
                      un stylo est un machin_pour_ecrire.
                      Tu peux remplacer n'importe quel machin_pour_ecrire par un stylo.

                      Pour le private:
                      Une pile est une implémentation classe_De_Stockage
                      • Partager sur Facebook
                      • Partager sur Twitter
                        30 mars 2008 à 22:22:07

                        C'est plus subtil que ça (pour les exemples)

                        Une liste triée sera implémentée en terme de liste (sans en "être-une"), et pourtant toutes deux pourraient être vue comme des séquences bi-directionnellement itérables qui proposent le retrait en O(1).

                        (Si je ne me suis pas plus étendu cette fois, c'est parce que j'ai déjà rabâché à n'en plus finir sur le sujet ; google est ton ami)
                        • Partager sur Facebook
                        • Partager sur Twitter
                        C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.

                        Je ne comprends pas l'héritage en protected

                        × 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