Partage
  • Partager sur Facebook
  • Partager sur Twitter

Contradiction ou malentendu ?

Au sujet des droits d'acces

    15 juin 2007 à 13:29:15

    Bonjour;

    En relisant les chapitres sur les classes, je viens de repérer une contradiction ou sinon c'est que je ne vois pas la différence:

    Citation : M@théo21


    void Personnage::attaquer(Personnage &cible)
    {
        cible.recevoirDegats(m_degatsArme); // On inflige à la cible les dégâts que causent notre arme
    }


    On ne peut pas modifier directement la vie de la cible en faisant cible.m_vie car la cible est un AUTRE objet (même s'il est aussi issu de la classe Personnage). On n'a le droit d'accéder qu'aux éléments publics de cet autre objet, donc à ses méthodes.


    Citation : M@théo21

    Personnage::Personnage(const Personnage &personnageACopier)
    {
        m_vie = personnageACopier.m_vie;
        m_mana = personnageACopier.m_mana;
    }


    Vous vous demandez peut-être comment cela se fait qu'on puisse accéder aux attributs m_vie et m_mana du personnageACopier ? Si vous vous l'êtes demandé, je vous félicite, ça veut dire que le principe d'encapsulation commence à rentrer dans votre tête :D
    Eh oui, en effet, m_vie et m_mana sont privés, donc on ne peut pas y accéder depuis l'extérieur de la classe... sauf qu'il y a une exception ici : on est dans une méthode de la classe Personnage, et on a le droit d'accéder à tous les éléments (même privés) d'un autre Personnage.

    C'est un peu tordu je l'avoue, mais dans le cas présent ça nous simplifie grandement la vie :) Retenez donc qu'un objet de type X peut accéder à tous les éléments (même privés) d'un autre objet s'il est du même type X.


    Est-ce que la différence correspond au fait que dans un cas on cherche à modifier les attributs et dans l'autre on ne fait que lire ?

    EDIT: A moins qu'il ne s'agisse que de pédagogie, histoire de ne pas nous embrouiller dès le début :lol:

    Si vous pouvez m'éclairer, merci !
    • Partager sur Facebook
    • Partager sur Twitter
      15 juin 2007 à 14:04:59

      Bah en fait, je pense que pour comprendre pourquoi on arrive à faire ce genre de truc il faut comprendre ce qu'implique de faire :

      m_vie = valeur;

      Dans une méthode de la classe Personnage.

      En fait quand tu écris ça, c'est comme si tu écrivais :

      this->m_vie = valeur;

      C'est-à-dire que tu accèdes implicitement aux attributs de l'objet sur lequel la méthode est appelée. "this" en l'occurrence est de type "*Personnage". C'est comme si tu transmettais sous forme de paramètre, l'objet qui exécute la méthode et que tu appelais ce paramètre "this".
      Donc comme chaque objet d'une même classe se situe dans la même portée, on peut accéder indifféremment aux attributs de "this" qu'aux attributs de Personnage. C'est justement ce qu'il dit dans le cours.

      Il commence par dire qu'on ne peut pas accéder aux attributs "private" d'un objet, mais comme la méthode Personnage::Personnage() se trouve dans la classe Personnage, on peut accéder à tous les attributs de tous les objets de cette même classe.
      • Partager sur Facebook
      • Partager sur Twitter
        15 juin 2007 à 14:50:11

        Ok mais, on pourrais alors recoder la méthode attaquer comme ceci :
        void Personnage::attaquer(Personnage &cible)
        {
            cible.m_vie-=m_degatsArme); // On inflige à la cible les dégâts que causent notre arme
        }


        Puisque cible est une référence vers un objet de type Personnage, et que la référence joue le rôle du pointeur "this" dont tu parlais en quelque sorte.
        • Partager sur Facebook
        • Partager sur Twitter
          15 juin 2007 à 16:07:28

          Je n'ai pas dit que la référence jouait le rôle du pointeur "this", j'ai dit que c'était à peu prés le même principe. Mais sinon... euh bah tu as en partie raison sur ce que tu fais là... En revanche, le principe de la programmation c'est de réutiliser du code déjà conçu, et la programmation objet a pour but d'encapsuler du code. Ici, tu dis que recevoir dégat c'est comme enelever de la vie, mais peut-^etre que recevoirDegat() fait autre chose, ou alors qu'on voudra un jour modifier l'implémentation de recevoirDegat() pour ajouter une finesse de gestion, qui impliquerait que la valeur de dégat ne soit pas égale à la valeur qu'on soustrait à la vie...
          • Partager sur Facebook
          • Partager sur Twitter
            15 juin 2007 à 16:13:41

            recevoirDegats est importante.

            Quand tu fais 10pts de dégat de feu, tu ne peux pas savoir combien de PV seront perdus. Seule la bestiole peut le savoir car elle seule connait ses immunités.

            Telle est l'encapsulation : faire abstraction des détails d'implémentation et offrir un service simple à utiliser.
            • 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.
              15 juin 2007 à 16:58:56

              OK j'ai bien compris la place de la poo dans l'histoire, et l'utilitée de la fonction recevoir dégats, mais synthaxiquement parlant, mon code est correct hein ?
              Je sais je suis chiant mais je veux en être sur parceque cette phrase de M@théo21 me fiche le doute, comme vous pouvez pas savoir ^^ :

              Citation : M@théo21

              On ne peut pas modifier directement la vie de la cible en faisant cible.m_vie car la cible est un AUTRE objet (même s'il est aussi issu de la classe Personnage). On n'a le droit d'accéder qu'aux éléments publics de cet autre objet, donc à ses méthodes.



              Ce n'est pas vrai donc ?
              Merci de vos réponses !
              • Partager sur Facebook
              • Partager sur Twitter
                15 juin 2007 à 21:58:17

                Pourquoi n'ouvres-tu pas ton IDE préféré et tu écris une petite classe de test ensuite dans ton main tu créer deux objet de la classe et tu fait des cout pour voir si cela fonctionne comme tu le pensais.

                Vaux mieux le voir de tes propres yeux et l'apprendre aisément plutôt que de recevoir 12 réponses tout aussi contradictoire que le cours de M@théo
                • Partager sur Facebook
                • Partager sur Twitter
                  17 juin 2007 à 23:37:41

                  La réponse de MatteX est pleine de sagesse : il ne faut pas avoir peur d'écrire des programmes de 20 lignes pour tester tel ou tel détail du C++ sur lequel on a un doute.
                  Cela m'arrive régulièrement, même pour des trucs qui semblent simples.


                  Sinon, dans l'absolu il y a une erreur dans le tuto. À partir du moment où les deux objets sont du même type, tu peux accéder aux champs privés du second objet.

                  Il est sûr que régulièrement deux objets de même type n'ont pas à accéder aux champs de l'autre objet, mais ce n'est pas ainsi que fonctionne le "private:" du C++.
                  • 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.
                    17 juin 2007 à 23:43:01

                    Citation : lmghs

                    Il est sûr que régulièrement deux objets de même type n'ont pas à accéder aux champs de l'autre objet, mais ce n'est pas ainsi que fonctionne le "private:" du C++.


                    Euh :euh: t'es sûr de toi là ?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      18 juin 2007 à 0:01:27

                      Oui.
                      struct T {
                          void f(T & other) {
                              other . i_ = 42;
                          }
                      private:
                          int i_;
                      };

                      int main (int argc, char **argv)
                      {
                          T a,b;
                          a.f(b);
                          return 0;
                      }


                      Que a puisse altérer la donnée privée de b est certes pas sage du tout (surtout s'il y a des contraintes sur cette donnée), mais c'est parfaitement possible.
                      • 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 juin 2007 à 0:06:20

                        Certain. On peut voir ça sous la forme : une classe A est forcément amie d'elle-même... Enfin c'est une façon de voir la chose.

                        Teste donc ce code :
                        #include <iostream>

                        using namespace std;

                        class A
                        {
                            int i;

                            public:
                            A() : i(10) { }
                            void f(const A& other)
                            {
                                cout << other.i + i << endl;
                            }
                        };

                        int main()
                        {
                            A a;
                            A b;
                            a.f(b);
                                return 0;
                        }
                        • Partager sur Facebook
                        • Partager sur Twitter
                          18 juin 2007 à 0:20:26

                          Je sais qu'un objet peut accéder aux variables d'instance d'un autre, ce que je ne comprenais pas c'est qu'il dise qu'on ait pas le droit.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            18 juin 2007 à 0:37:14

                            On en a le droit. Mais parfois, il serait plus sage que l'on ne dispose pas de ce droit.
                            • 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 juin 2007 à 0:51:04

                              En effet, le principe de l'encapsulation étant de fermer l'accès direct au attributs d'une classe/structure, et de passer par des méthodes permettant ou non la modification des attributs, ce qui est beaucoup plus sur pour la stabilité d'une application.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                18 juin 2007 à 0:56:57

                                l'encapsulation c'est surtout empêcher les autres objets d'accéder à la structure d'un objet, pas vraiment d'empêcher l'accès des objets d'une même famille.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  18 juin 2007 à 1:05:07

                                  Le principe derrière l'encapsulation, c'est de faire abstraction des détails d'implémentation. Ce n'est rien d'autre.

                                  L'encapsulation est le détail d'implémentation (sic) OO qui permet de réaliser cela.
                                  • 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 juin 2007 à 11:38:18

                                    Merci beaucoup pour vos réponses :)
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Contradiction ou malentendu ?

                                    × 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