Partage
  • Partager sur Facebook
  • Partager sur Twitter

Acces à un membre protégé d'une classe mère

depuis une méthode de classe fille

    16 octobre 2020 à 9:06:23

    Bonjour,

    Soit F une classe fille de M, M possédant un membre donné protected m_x.

    Soit une méthode de la classe fille F: public M , écrite comme ceci :

    void F::methode( M &  obj_M ){

    std::cout << "accès à un membre protégé d'un objet de la classe mère... impossible !" << obj_M.m_x << endl ;

    // ceci est refusé

    }

    Le qualificatif "protected" serait-il circonscrit à l'héritage d'objet en objet, et non de classe en classe ?

    Je ne dois pas capter quelque chose...

    }

    • Partager sur Facebook
    • Partager sur Twitter
      16 octobre 2020 à 9:11:48

      L'utilisation de la portée protected sert à autoriser l'accès aux sous-classes d'une variable membre parente. Elle n'autorise en aucun cas un accès à une classe externe.

      Pour accéder à une variable/fonction privée/protected depuis une autre classe il faut utiliser le mot clé friend, mais celui ci donne accès à toute la classe.

      -
      Edité par markand 16 octobre 2020 à 9:14:06

      • Partager sur Facebook
      • Partager sur Twitter

      git is great because Linus did it, mercurial is better because he didn't.

        19 octobre 2020 à 15:02:50

        Bonjour,

        J'ai bien précisé que la classe fille F héritait de M... et une méthode d'une classe héritée ( F en l'occurence )  devrait donc accéder à un attribut de sa classe mère si elle est de portée "protected".

        Par ailleurs je ne comprends pas votre dénomination "sous-classe d'une variable membre parente".

        La notion de sous-classe et d'héritage est une relation entre classes, quid de cette "variable membre parente" ?...

        Bref, normalement une méthode de classe fille devrait bien accéder à un membre protected de sa classe parent non, puisque c'est sa vocation?

        Bonjour Zoup, je n'ai plus le message d'erreur mais je pourrai le retrouver.

        En gros c'était access denied au membre protected de l'objet de la classe mère transmis par référence à la méthode de la classe fille.

        Refus catégorique du compilateur.

        Il semble en fait que la portée protected soit effective seulement au sein de l'objet, pas entre objet-fille et objet-parent s'ils sont potentiellement différents à l'appel de la méthode ( ce que le compilateur ne peut pas savoir ). En résumé

        Obj_B accède à Obj_B_membre_protégé ( de sa classe parente A ) , pas à Obj_A_membre_protégé ( aussi de sa classe parente, mais Obj_A pouvant être différent de Obj_B ).

        J'espère avoir été plus clair.

        -
        Edité par rodot 19 octobre 2020 à 15:38:50

        • Partager sur Facebook
        • Partager sur Twitter
          19 octobre 2020 à 15:18:57

          rodot a écrit:

          void F::methode( M &  obj_M ){

          std::cout << "accès à un membre protégé d'un objet de la classe mère... impossible !" << obj_M.m_x << endl ;

          // ceci est refusé

          Quel est le message d'erreur?

          • Partager sur Facebook
          • Partager sur Twitter
            19 octobre 2020 à 15:23:54

            Pour mieux peut-être faire comprendre ( et fixer les idées ) du problème soit une classe B qui dérive d'une classe A et un membre donné

            m_A de la classe mère A, qui soit private.

            Si obj_1A et obj_2A sont  de la classe A, et method_A() de la classe A , obj_1A.method_A() pourra accéder directement  au champ obj_2A

            de sa classe. Les objets sont différents, mais de la même classe, et c'est OK.

            Si obj_B par contre veut accéder directement à un champ protected d' obj_A ( pourtant de sa classe parente ) , cela ne fonctionne pas:

            le compilateur semble couper les ponts d'accès aux champs entre objets différents , même s'il y a un héritage de classe et une portée protected.

            C'est pourquoi je pense que la portée protected n'est transmise qu' à l'intérieur du même objet : un attribut protected d'un autre objet de la class-mère n'est pas mieux accessible qu'en private par un objet d'une classe-fille ( c'est à dire pas accessible ).

            Le message du compilateur était: error: 'int Personnage::m_nivVie'  is protected within this context.

            Pour faire quelques tests d'héritage, j'ai fait dériver une class Magicien de la class Personnage.

            la class Personnage a été doté d'un attribut protected m_nivVie entier.

            La class Magicien possède un champ m_mana spécifique.

            Le pb se pose quand j'écris une méthode de Magicien::jeterSort( Personnage & p ) avec dans le corps de la méthode p.m_nivVie -= m_mana; 

            Le niveau de pouvoir du magicien (noir ) , son mana, doit faire baisser le niveau de vie de sa victime...

            Ca coince même si m_nivVie est de portée protected dans la classe mère Personnage.

            -
            Edité par rodot 19 octobre 2020 à 16:14:15

            • Partager sur Facebook
            • Partager sur Twitter
              19 octobre 2020 à 15:51:37

              Si je comprends bien tu veux parler d'un code comme celui-ci ?

              class A{
              
              public:
              
                  A(int a) : a_(a)
                  {}
              
              protected:
                  int a_;
              };
              
              class B : public A{
              
              public:
              
                  B(int a) : A(a)
                  {}
              
                  void fooB(const A& objetA)
                  { std::cout << "Attribut a_ de l'objet de type B : " << a_ << std::endl;
                    std::cout << "Attribut a_ de l'objet de type A : " << objetA.a_; // Ligne problématique }
              };

              Ce n'est effectivement pas possible : ce que tu tentes de faire ici c'est un peu comme si tu allais dans une autre fonction, totalement indépendante de la classe B, et que tu faisais :

              void foo(){
                 
                 B objetB { 10 };
                 // Ici on imaginerait une tentative d'accès à l'attribut a_ de objetB : objetB.a_
              }

              Tu ne peux accéder aux éléments protected que lorsque tu manipules des objets de la classe qui héritent dans cette même classe

              -
              Edité par AmirProg 19 octobre 2020 à 15:56:26

              • Partager sur Facebook
              • Partager sur Twitter
                20 octobre 2020 à 8:58:36

                Bonjour,

                OUi c'est bien cela, finalement je m'étais rendu compte moi-même de l'impossibilité en reprenant la bible de Stroustrup hier soir, on ne peut accéder aux membres "protected" qu'entre classes vraiment du même type ( objets distincts ou pas ). Un attribut protected d'une classe-mère ( n'étant pas du même type que sa classe-fille évidemment ) n'est donc pas accessible depuis une méthode de cette classe-fille.

                Merci quand-même.

                Cordialement.

                • Partager sur Facebook
                • Partager sur Twitter
                  20 octobre 2020 à 13:03:23

                  A propos des modificateurs d'accès private/protected, il y a deux conceptions fausses très répandues chez les débutants (C++, Java etc). 

                  1. c'est que ça serait pour empêcher d'accéder aux données ou fonctions membres (attributs et méthodes) s/code) d'un objet, pour en quelque sorte protéger cet objet.

                  2. Ca serait pour protéger contre les agissements d'un autre objet.


                  Déjà, le premier point, c'est évident que c'est faux, parce que ça concerne aussi les membres statiques, qui sont pas membres d'objets.

                  Ensuite, le second point, ça pousse le débutant à croire qu'il n'a pas le droit d'écrire

                  class A {
                  private:
                  	int my_x = 0;
                  
                  public:
                  	A (int x) {
                  		my_x = x;
                  	}
                  	
                  	void ajouter (A &other) {
                  		my_x  += other.my_x;
                  	}
                  };


                  au prétexte que la fonction A::ajouter accèderait au my_x d'un autre objet... Et du coup, il va se sentir obligé d'ajouter un accesseur public, pour faire    my_x += other.get_x(); ce qui est inutile et même franchement nuisible.

                  En réalité, les modificateurs d'accès, c'est relatif au code des classes.

                  Exemple : si un membre est "protected"  dans une classe A, ça veut dire qu'il peut être accédé depuis le code de la classe A elle-même, et des classes qui en dérivent. (+ les friends, autre embrouille).

                  -
                  Edité par michelbillaud 20 octobre 2020 à 13:04:50

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Acces à un membre protégé d'une classe mère

                  × 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