Partage
  • Partager sur Facebook
  • Partager sur Twitter

problème avec la portée protected

Sujet résolu
    17 septembre 2007 à 22:38:55

    Un petit copier-coller pour vous présenter la situation :

    fichier personnage.h
    1. #ifndef DEF_PERSONNAGE
    2. #define DEF_PERSONNAGE
    3. #include "Arme.h"
    4. #include <string>
    5. class Personnage
    6. {
    7.     public:
    8.     Personnage();
    9.     Personnage(std::string nom, std::string classe);
    10.     Personnage(const Personnage &personnageACopier);
    11.     ~Personnage();
    12.     void recevoirDegats(int nbDegats);
    13.     void attaquer(Personnage &cible);
    14.     void boirePotionDeVie(int quantitePotion);
    15.     void changerArme(std::string nomNouvelleArme, int degatsNouvelleArme);
    16.     bool estVivant();
    17.     void afficherEtat();
    18.     std::string getNom();
    19.     protected:
    20.     std::string m_nom;
    21.     int m_vie;
    22.     int m_mana;
    23.     Arme *m_arme;
    24. };
    25. #endif


    fichier guerrier.h
    1. #ifndef DEF_GUERRIER
    2. #define DEF_GUERRIER
    3. #include <iostream>
    4. #include <string>
    5. #include "Personnage.h"
    6. class Guerrier : public Personnage
    7. {
    8.     public:
    9.     Guerrier(std::string nom);
    10.     Guerrier(const Guerrier &guerrierACopier);
    11.     ~Guerrier();
    12.     void utiliserArmeSpeciale(Personnage &cible);
    13.     protected:
    14.     Arme *m_armeSpeciale;
    15. };
    16. #endif


    fichier guerrier.cpp(extrait)
    1. void Guerrier::utiliserArmeSpeciale(Personnage &cible)
    2. {
    3.     cout << m_nom << " a utilisé son ARME SPECIALE (" << m_armeSpeciale->getNom() <<", dégats " << m_armeSpeciale->getDegats() << " ) contre " << cible.m_nom << endl;
    4.     cible.recevoirDegats(m_armeSpeciale->getDegats());
    5. }


    et le commentaire du compilateur :

    Citation : build log

    Guerrier.cpp: In member function `void Guerrier::utiliserArmeSpeciale(Personnage&)':
    Personnage.h:24 : error: `std::string Personnage::m_nom' is protected
    Guerrier.cpp:28 [3 ici] : error: within this context



    Bref pour résumer, je ne peux pas accéder à l'attribut "m_nom" de la classe "Personnage" depuis la classe fille "Guerrier" alors que celui-ci est classé "protected". Evidemment je peux utiliser un accesseur mais dans ce cas l'intérêt de la portée protected est quelque peu limité. :euh: Comment faire ? :o J'attends vos conseils de professionnels. :)

    (ne vous étonnez pas si je ne vous réponds pas ce soir, je vais me coucher et lirai vos précieuses indications demain à tête repsée).
    • Partager sur Facebook
    • Partager sur Twitter
      18 septembre 2007 à 0:32:37

      Citation : Lutinbleu

      Bref pour résumer, je ne peux pas accéder à l'attribut "m_nom" de la classe "Personnage" depuis la classe fille "Guerrier" alors que celui-ci est classé "protected". Evidemment je peux utiliser un accesseur mais dans ce cas l'intérêt de la portée protected est quelque peu limité. :euh: Comment faire ? :o


      tu ne peux pas car tu accèdes à la variable m_nom d'une autre variable. Si tu mets "m_nom" tout seul tu pourras.

      ps : je sais qu'en java c'est possible. Et en C++ çà l'est (Imghs & co) par exemple, quand on est dans la même classe et non une classe dérivée ?
      • Partager sur Facebook
      • Partager sur Twitter
        18 septembre 2007 à 2:13:16

        Si mes souvenirs sont bons (à force ne pas faire des trucs relativement bizarres (pour en faire d'autres), on oublie ces trucs), il pourrait accéder au m_nom d'un autre guerrier, mais pas à celui d'un autre personnage. Car rien ne dit que le personnage ne soit pas en fait un Ranger.

        Les droits d'accès ne portent pas uniquement sur les membres de la variable courante.

        Un accesseur pourrait parfaitement faire l'affaire ici:
        1. class Personnage // : boost::noncopyable
        2. {
        3. public:
        4.     Personnage(std::string const& nom) : m_nom(nom) {}
        5.     std::string const& getNom() const { return m_nom; }
        6.        //            ^-- car renvoie un attribut et pas une chaine calculée
        7. private
        8.     std::string m_nom;
        9. };



        NB: Un identifiant est un truc un peu particulier. Cela peut vraiment être vu comme une propriété en lecture seule. Donc avoir un accesseur dessus a parfaitement du sens.

        Pour d'autres choses (genre le score d'attaque de base), cela n'aurait pas à être exposé. A la place, une fonction attaquer() pourrait renvoyer une Attaque qui dans sa description stipule le type d'attaque (sort/epée rouillée, ...), la classe d'armure touchée, comment se résolvent les dégats.
        La cible en fonction de son armure courante résoudra si elle est touchée, puis encaissera en fonction des protection/immunités courantes (comme ça, chacun garde ses stats et ses secrets)
        • 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.
          18 septembre 2007 à 17:03:43

          C'est le genre de trucs où un accesseur se justifie pleinement pour ne pas avoir besoin de retenir 50'000 règle d'accés.

          Cependant, je crois me souvenir que l'on peut accéder que aux m_nom d'une autre instace de Guerrier.

          Quand on dit que tu peux accéder aux variables protected, on veut dire que l'instance à le droit de modifier ses propres variables héritées de Personnage qui sont protected
          • Partager sur Facebook
          • Partager sur Twitter
          Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
            18 septembre 2007 à 17:27:26

            Ah, d'accord quand Matéo parle d'accéder aux attributs depuis une classe fille, ils ne parle pas des attributs de la classe mère mais des attributs de la classe fille héritées de la classe mère. Maintenant, je comprends.
            Merci à tous trois pour ces éclaircissements et bonne continuation. :)
            • Partager sur Facebook
            • Partager sur Twitter

            problème avec la portée 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