Partage
  • Partager sur Facebook
  • Partager sur Twitter

Class et pointeur

Class et pointeur

Sujet résolu
    15 septembre 2017 à 14:21:22

    Artanno62 a écrit:

    Je serais curieux de savoir ou ça fuit :p

    Bah :

    class Distributeur{
    private:
        CreditCard *m_userCard;
    public:
        Distributeur(const CreditCard &userCard){
            m_userCard = new CreditCard;
            m_userCard->m_Name = userCard.m_Name;
            //on a recu "userCard" en entree et on ne l'a pas utilisee
        }
        void retirerCarte(){
            // pouf ! on vient de retirer la carte sans la libérer
            m_userCard = nullptr;
        } 
        void insererCarte(const CreditCard &userCard){
            // pouf ! on remplace la carte sans libérer celle potentiellement présente
            m_userCard = new CreditCard;
            m_userCard->m_Name = userCard.m_Name;
            //on a recu "userCard" en entree et on ne l'a pas utilisee
        }
    };
    • Partager sur Facebook
    • Partager sur Twitter

    Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

      15 septembre 2017 à 14:51:55

      Oui effectivement! Merci!! :)

      Edit*

      Comment je peux modifier ça pour libérer la carte? Je vois pas trop se que je peux faire à ce niveau à part ne pas utiliser de pointeur (Par curiosité, de toute façon je n'utilise plus les pointeurs pour refaire mon code la)

      -
      Edité par 238 15 septembre 2017 à 14:55:19

      • Partager sur Facebook
      • Partager sur Twitter
        15 septembre 2017 à 14:56:44

        >Comment je peux modifier ça pour libérer la carte?

        Utilisez des pointeurs intelligents. ;)

        • Partager sur Facebook
        • Partager sur Twitter
        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
          15 septembre 2017 à 15:10:41

          Tout simplement :p

          Merci!

          Edit:

          Pourquoi Koala dans ton exemple de code, tu mets une fonction private qui retourne le code de la carte de crédit alors que dans tous les cas la classe distributeur a accés aux elements privés de credit card par amitié?

          En gros c'est quoi l'interet d'écrire

          c.getCode(); // Toi tu as juste écris c.code() dans la classe distributeur

          plutôt que

          c.secretpass;

          Si j'ai bien compris, c'est en fonction de se que l'utilisateur du distributeur à accés ou non? Ca reste un peu flou à mon sens cette partie de code..

          Autant supprimer la fonction, et utiliser directement l'attribut étant donné qu'ils sont amis

          -
          Edité par 238 15 septembre 2017 à 21:08:05

          • Partager sur Facebook
          • Partager sur Twitter
            15 septembre 2017 à 15:53:53

            La qualité cardinale d'une bonne conception est de rendre simple l'implémentation de la solution logicielle.

            Une chose qui tend à rendre l'usage de composant logiciel simple, c'est de les rendre indépendant les uns des autres.

            La modularisation et l'encapsulation permettent de renforcer facilement l'indépendance.

            En passant par un accesseur, comme getCode, c'est un moyen primitif de rendre Distributeur et CreditCard un peu plus indépendant.

            Pour avoir travaillé il y a plusieurs décennies dans la carte bancaire, je n'airais pas modéliser la chose de cette manière.

            Le code n'est pas communiqué entre la carte et le distributeur mais juste des résultats de hash d'un challenge-response.

            La carte génère une valeur aléatoire, la communique au distributeur, le distributeur utilise le code entré par l'utilisateur pour hashé la valeur aléatoire, et envoie le résultat à la carte qui elle dit OK ou non (elle aussi fait le hash).

            Si tu modélises cela, tu vois que l'accès directement aux membres d'une classe n'est que très rarement une bonne solution car elle empêche l'évolution de l'implémentation de la classe "accédée" sans avoir à toucher à toutes les classes "accédantes". Friend permet de réduire le nombre de classe mais elles sont toujours impactées, donc boule de neige de modifications toujours possible.

            Avec l'utilisation d'un accesseur, il serait possible de "calculer" le code sans avoir à changer le code utilisateur de la classe.

            Mais bon, avec une interface plus proche de la réalité, la question ne se pose même pas.

            -
            Edité par bacelar 15 septembre 2017 à 17:26:23

            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              15 septembre 2017 à 16:10:17

              Super pour l'explication, c'est compris

              Merci :)

              • Partager sur Facebook
              • Partager sur Twitter
                15 septembre 2017 à 18:10:12

                Il est vrai que, à y réfléchir plus correctement, on pourrait dire que la vérification d'un code secret et la possibilité de modifier le code secret de la carte sont autant de services que l'on est en droit d'attendre de la part de la carte de crédit. 

                Nous pourrions donc supprimer l'amitié entre le distributeur et la carte de crédit et transformer la carte de crédit pour lui donner une forme proche de

                class CreditCard{
                public:
                    CreditCard(std::string const & name,
                               std::string const & surname,
                               date expiration, unsigned int code)
                               :name_{name}, surname_{surname},
                                expiration_{expiration}, code_{code},
                                tries_{0}{}
                    date const & expiration() const{return expiration_;}
                    std::string const & userName() const{return name_;}
                    std::string const & userSurName() const{return name_;}
                    bool blocked() {return tries_=3;}
                    bool checkCode(unsigned int code) const{
                       if(code == code){
                           codeAccepted();
                           return true;
                       }
                       codeRejected();
                       return false;
                    }
                    bool changeCode(unsigned int currentCode, 
                                    unsigned int newCode){
                        bool check = checkCode(code);
                        if(! check)
                            return false;
                        code_==newCode;
                        return true;
                    }
                private:
                    void codeAccepted(){tries_=0;}
                    void codeRejected(){++ tries_;}
                    std::string name_;
                    std::string surname_;
                    date expiration_;
                    unsigned int code_;
                    unsigned int tries_;
                 
                };

                @bacelar : je présumes que, sous cette forme, c'est déjà beaucoup plus proche (à l'exception du type utilisé pour représenter le code, et de toute sa gestion interne)  de l'interface que tu utilisais ?

                @Artanno62 : le but de l'encapsulation n'est pas de cacher les données pour le plaisir de le faire, mais bien de faire en sorte que l'utilisateur d'une donnée ne puisse pas faire de connerie en la manipulant.

                Il est vrai que, lorsqu'on empêche l'utilisateur d'accéder directement à une donnée, on a d'autant plus facile d'éviter qu'il ne fasse une connerie en la manipulant.  Mais cela ne résout malgré tout qu'une partie du problème, car une donnée n'a réellement de sens que s'il est possible de la manipuler: une donnée que tu ne peut manipuler d'aucune manière est une donnée qui ne sert à rien et qui est donc inutile dans ton programme.

                En réalité, ce qu'il faut surtout faire, c'est poser "des jalons" qui permettent à l'utilisateur de savoir "ce qu'il peut faire" avec la donnée en question en lui fournissant une liste de fonctions qu'il peut appeler dans le cadre de l'utilisation de la donnée.

                Bien sur, nous veillerons à ce que les fonctions que nous mettons à disposition de l'utilisateur soient vérifiables, vérifiées et qu'elles fassent le boulon qu'on attend de leur part.

                A partir du moment où l'on fournit à l'utilisateur les fonctions qui permettent de manipuler une donnée de manière sécurisante, on s'en fout pas mal que la donnée en question soit accessible ou non: 

                Soit il utilisera la donnée de la manière que nous aurons préconisée, et il ne devrait avoir aucun problème, soit "il fait le con" en allant chipoter à des choses auxquelles il n'aurait jamais du toucher.  Mais, dans ce cas, il ne pourra s'en prendre qu'à lui-même ;)

                Alors, bien sur, si on fournit à l'utilisateur un ensemble de fonctions qui lui permettent de manipuler des données auxquelles il n'a pas d'accès "direct", c'est encore mieux, car ça lui évitera sans doute la tentation de "faire le con" en allant chipoter à ce qu'il ne doit pas.

                Mais s'il y a une chose à retenir au final, c'est que toutes les manipulations que tu peux envisager sur une donnée quelconque doivent être "garantie sans danger", et que le seul moyen de fournir cette garantie est de ... fournir une fonction qui effectuera la manipulation et les vérifications nécessaires.

                C'est dans cette optique que j'avais fourni des fonctions privée checkCode et changeCode : pour garantir que, si "quelque chose" passait par ces fonctions, le résultat serait correct, vérifiable et reproductible.  Chose que je n'aurais jamais pu garantir si j'avais laissé la classe Distributeur accéder "à sa guise" à la donnée membre "code_" ;)

                • Partager sur Facebook
                • Partager sur Twitter
                Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                  15 septembre 2017 à 18:45:09

                  >@bacelar : je présumes que, sous cette forme, c'est déjà beaucoup plus proche

                  Les réponses à l'ATR et les commandes au format ISO avec code retour sur 2 octets passant par une communication série, c'est pas très "objet". ;)

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                    15 septembre 2017 à 21:12:18

                    Clair et net. J'ai tout compris! Merci beaucoup pour avoir pris tout le temps de m'expliquer avec du code à l'appuie, je pouvais pas espérer mieux.

                    Sujet résolu!

                    Merci encore! :)

                    Arta.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      15 septembre 2017 à 21:37:04

                      Une carte bancaire est une forteresse, il est hors de question de laisser quiconque lui demander quel est ton code. Le principe est plutôt:

                      La carte pose une question, le distributeur demande le code à l'utilisateur, se sert du code pour composer une réponse à la carte. En fonction de la réponse, la carte répond oui ou non. Si le distributeur pouvait demander son code à la carte, il serait trop facile de faire de faux distributeurs. Faire de fausse cartes est nettement plus compliqué et les distributeurs ont eux aussi des challenges pour détecter les fausses cartes. On ne peut pas vraiment dire que la confiance règne ^^

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                        18 septembre 2017 à 11:20:27

                        >des challenges pour détecter les fausses cartes

                        Qui n'étaient pas super au point => les "yes cards". ^^

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                        Class et pointeur

                        × 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