Partage
  • Partager sur Facebook
  • Partager sur Twitter

Classe Fraction : le cas de la division par 0

Comment la gerer....?

Sujet résolu
    19 octobre 2018 à 16:52:04

    Hello World!

    Je suis en train de crée la classe ZFraction demande dans le cours de C++ d'Openclassrooms et en faisant quelques tests j'ai remarque que la division par 0 faisais planter mon programme... Du coup j' était parti pour faire une gestion d’erreurs a coup de true/false comme en C cependant le constructeur de ma Fraction ne "return" seulement une Fraction par definition... Donc si je veux arrêter mon programme et dire a mon utilisateur que sa fraction ne vas pas... soit c'est exit() mais c'est pas propre soit je sais pas... Comment faut - il gérer ce cas? :euh:

    Je vous pose mon code ici bas:

    Fraction.h

    class Fraction
    {
        public:
            Fraction(int x = 0, int y = 1);
            void show() const;
            void simplify();
            int getNumerator() const;
            int getDenominator() const;
        private:
            int mX{0};
            int mY{1};
    };


    Fraction.cpp

    Fraction::Fraction(int x, int y) : mX{x}, mY{y}
    {
        int pgcd = findPGCD(mX, mY);
    
        if (pgcd != 0) {
            mX /= pgcd;
            mY /= pgcd;
        }
        if ((mX < 0 && mY < 0) || (mX > 0 && mY < 0)) {
            mX *= -1;
            mY *= -1;
        }
    }
    
    void Fraction::show() const
    {
        if (mX == 0)
            std::cout << "0" << std::endl;
        else if (mY == 1)
            std::cout << mX << std::endl;
        else
            std::cout << mX << "/" << mY << std::endl;
    }
    
    int findPGCD(int a, int b)
    {
        if (a == b)
            return (a);
        return (a % b == 0 ? b : findPGCD(b, a % b));
    }

    Merci d'avance ! :D


    PS: Si vous avez des commentaires sur la qualite du code, je prend! :-°

    PS: Je sais deja que le cours c++ d'OC est mauvais ^^

    • Partager sur Facebook
    • Partager sur Twitter
    Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime.
      19 octobre 2018 à 17:05:37

      Lu'!

      Par une assertion à la construction qui vérifie que le dénominateur ne s'évalue pas à 0.

      • Partager sur Facebook
      • Partager sur Twitter

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

        19 octobre 2018 à 17:32:46

        Avant de construire ton objet, vérifie que le numérateur est non nul. Dans le constructeur tu pourras ensuite mettre une assertion.

        cf mes 3 billets sur la PpC pour de plus amples détails: http://luchermitte.github.io/blog/2014/05/24/programmation-par-contrat-un-peu-de-theorie/ (le sujet est parfois complexe quand on a peu d'expérience: il est difficile de vraiment saisir quel est le meilleur endroit où faire les vérifications)

        • 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.
          22 octobre 2018 à 10:20:56

          Ksass`Peuk a écrit:

          Lu'!

          Par une assertion à la construction qui vérifie que le dénominateur ne s'évalue pas à 0.


          lmghs a écrit:

          Avant de construire ton objet, vérifie que le numérateur est non nul. Dans le constructeur tu pourras ensuite mettre une assertion.

          cf mes 3 billets sur la PpC pour de plus amples détails: http://luchermitte.github.io/blog/2014/05/24/programmation-par-contrat-un-peu-de-theorie/ (le sujet est parfois complexe quand on a peu d'expérience: il est difficile de vraiment saisir quel est le meilleur endroit où faire les vérifications)


          Mais je vois pas comment je peux vérifier mon numérateur avant d'appeler mon constructeur, puisque celui ci est appelle lorsque je crée ma variable?
          • Partager sur Facebook
          • Partager sur Twitter
          Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime.
            22 octobre 2018 à 10:30:43

            Ta construction n'est effective qu'après avoir terminé l'exécution du bloc du constructeur. Donc simplement :

            Q::Q(int num, unsigned den) : 
              m_num{ num },
              m_den{ den }
            {
              assert(den != 0) ;
            }

            Si ton dénominateur est 0 à l'entrée, ça pètera l'assertion et le programme crashera purement et simplement. Interdisant ainsi au développeur de mettre 0 comme dénominateur.

            • Partager sur Facebook
            • Partager sur Twitter

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

              22 octobre 2018 à 10:37:57

              class Rationnel {
                  explicit Rationnel(int n = 0, int d = 1)
                   : num(n), den(d)
                  {
                      assert(d >= 0);
                      reduit();
                  }
              private:
                  void reduit();
                  int num;
                  int den;
              };
              
              void unefonction___ailleurs()
              {
                  int n, d;
                  if (! (std::cin >> n >> d)) {
                      throw std::runtime_error("Impossible de lire deux entiers dans le flux");
                      // Pour bien fair,e il faudrait tester std::cin.eof() pour vérifier si l flux a été fermé -- cf FAQ: valider les saisies
                  }
                  if (d < 0) {
                      throw std::runtime_error("Un nombre positif est attendu pour un dénominateur");
                  }
                  if (d == 0) {
                      throw std::runtime_error("Un nombre non null est attendu pour un dénominateur");
                  }
              
                  // Et là, on a le rationel
                  const Rationnel r{n, d};
              }
              • 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.
                22 octobre 2018 à 11:20:54

                Ca serait peut être mieux de lancer une exception spécifique.

                class ExceptionConstructionRationnel 
                	: public std::runtime_error
                {
                public:	
                	ExceptionConstructionRationnel() 
                		: std::runtime_error("dénominateur nul") 
                	{
                	}
                };
                
                class Rationnel {
                	int num;
                    int den;
                
                public:
                    Rationnel(int n = 0, int d = 1)
                     : num(n), den(d)
                    {
                        if (d == 0) {
                	        throw ExceptionConstructionRationnel();
                        }
                    }
                };
                



                -
                Edité par michelbillaud 22 octobre 2018 à 11:21:44

                • Partager sur Facebook
                • Partager sur Twitter
                  22 octobre 2018 à 11:40:32

                  Salut,

                  Oui, d'une certaine manière, ce serait en effet mieux d'avoir une exception spécifique, mais non, il ne faut pas lancer une exception au niveau du constructeur de la classe, car le fait que le dénominateur doit être non nul, c'est aussi une pré condition, que le développeur doit s'assurer de respecter...

                  Au niveau du constructeur, nous devrions donc utiliser une assertion, car un dénominateur nul représentera toujours une erreur de logique.

                  Au niveau de la fonction qui extrait les valeurs d'un flux, nous devrions utiliser une exception, car une valeur nulle lors de l'extraction du dénominateur est une situation "dont on espère qu'elle ne se produira jamais" sans pour autant pouvoir garantir que ce sera le cas ;)

                  • 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
                    22 octobre 2018 à 11:40:42

                    Dans le constructeur ? Oh bah non alors.

                    • Partager sur Facebook
                    • Partager sur Twitter

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

                      22 octobre 2018 à 11:56:12

                      mais personne n'oblige le programmeur à rattraper les runtime exceptions, ce qui lui demande un travail _explicite_. Et on peut supposer que si il le fait, c'est qu'il a des raisons qui lui appartiennent.

                      Alors que les assertions désactivés par accident, ça arrive (dans les options de compilation).

                       
                      #define NDEBUG 
                       

                      -
                      Edité par michelbillaud 22 octobre 2018 à 11:57:36

                      • Partager sur Facebook
                      • Partager sur Twitter
                        22 octobre 2018 à 12:14:32

                        veux-tu dire que pour désactiver les assertions, on peut ajouter dans le code

                        #define NDEBUG ?

                        ou c'est dans l'IDE qu'il faut ajouter cela ?

                        • Partager sur Facebook
                        • Partager sur Twitter
                          22 octobre 2018 à 12:20:59

                          michelbillaud a écrit:

                          mais personne n'oblige le programmeur à rattraper les runtime exceptions, ce qui lui demande un travail _explicite_. Et on peut supposer que si il le fait, c'est qu'il a des raisons qui lui appartiennent.

                          Alors que les assertions désactivés par accident, ça arrive (dans les options de compilation).

                           
                          #define NDEBUG 
                           

                          -
                          Edité par michelbillaud il y a moins de 30s

                          Nous sommes bien d'accord, tout comme nous sommes bien d'accord que, selon la manière dont le flux est rempli, nous ne pourrons rien faire si le dénominateur est nul.

                          Mais, a priori, tout bon développeur a au moins conscience du fait que sa logique doit être sans faille (elle peut ne pas être "aussi efficace que possible", elle doit au moins être ... juste), et qu'il y a donc une série de tests à faire :

                          • Des tests unitaire (dont certains peuvent clairement "faire péter" les assertions)
                          • des "tests du singe" qui permettront de s'assurer que l'utilisateur distrait ne fera pas "tout pêter"

                          Le simple fait d'avoir un test qui devrait faire péter l'assertion, mais qui ne le fait pas devrait indiquer ce problème de configuration ;)

                          • 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
                            22 octobre 2018 à 13:22:47

                            Michel, c'est le problème de qui doit faire quoi.

                            Si on met l'exception dans le constructeur, on est dans le cas que j'ai décris dans mon premier billet de blog sur la PpC: OK, on ne plante pas, OK les inputs externes sont incidemment testées, mais on ne remonte pas de messages d'erreur intelligibles, et on paie tout le temps des tests dont on peut se passer une fois les inputs validées.

                            Je suis de moins en moins persuadé qu'il est une bonne chose de lancer des exceptions depuis des constructeurs. Pas qu'il ne faille pas en lancer, mais que les tests devraient être faits en amont, là où l'on sait ce que l'on essaie de faire à partir de quoi.

                            Quitte à forcer l'utilisateur à procéder correctement, on peut jouer avec

                            // TODO: ajouter constexpr, noexcept, les conversions implicites avec strictly_positive<U>, etc
                            template <typename T>
                            struct striclty_positive {
                                explicit striclty_positive(int i) n:(i)
                                { assert(i > 0); }
                                explicit operator int() const { return n };
                            private:
                                int n;
                            };
                            
                            class Rational
                            {
                            public:
                                Rational(int n, strictly_positive<int> d);
                            ...
                            };



                            • 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.
                              22 octobre 2018 à 13:43:48

                              @lmghs : à titre de curiosité pour progresser (je sais que ça fait beaucoup de questions, mais ça m'intéresse de comprendre maintenant que j'ai fini le cours de Mateo21, car ces points ne sont pas dans son cours et avec la doc je n'ai pas compris) :

                              1) à quoi sert explicit dans cet exemple (tu l'as utilisé deux fois  : une fois avec le constructeur et l'autre avec ton opérateur) ?

                              2) que signifie la notation : operator int() ?

                              3) qund tu parles de TODO ajouter : constexpr, et noexcept, peux-tu m'expliquer à quoi servent ces deux mots-clés ici ?

                              Merci

                              -
                              Edité par pseudo-simple 22 octobre 2018 à 13:44:27

                              • Partager sur Facebook
                              • Partager sur Twitter
                                22 octobre 2018 à 14:08:47

                                Ca fait beaucoup à expliquer, je passe en mode fainéant

                                1- https://stackoverflow.com/questions/121162/what-does-the-explicit-keyword-mean

                                2- opérateur de conversion, explicite (c++11) -- en gros, on converti dans l'autre sens.

                                3- Prends-ton temps, tu n'y es pas encore. Le premier permet d'exiger du compilateur la garantie que des expressions seront évaluées à la compilation. Le second garantit qu'une fonction ne lance pas d'exception -- c'est plus compliqué en vrai. Comprends et vis d'abord le RAII.

                                • 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.
                                  22 octobre 2018 à 14:36:09

                                  Quand je vois ce lien sur explicit, je commence à me demander si dans le constructeur d'une classe, il ne faudrait pas systématiquement utiliser explicit ?

                                  -
                                  Edité par pseudo-simple 22 octobre 2018 à 14:36:34

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    22 octobre 2018 à 14:40:14

                                    Salut,

                                    Tu peux l'utiliser systématiquement sur les classes à sémantique d'entité

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Dream on, Dream on, Dream until your dream comes true
                                      22 octobre 2018 à 14:49:48

                                      Alors pour le coup, je suis pas sur de tout comprendre ni de quel méthode empreinte :euh:  a la différence du C, il y a plusieurs moyens de faire cela? Si j'ai bien suivi il y a 3 méthodes: 

                                      - la méthode qui utilise assert, qui va servir a faire juste crasher le programme si la condition est valide:

                                      assert(y != 0);

                                      - la méthode  qui utilise throw, qui va "jeter" une information du type erreur, qu'une autre fonction va rattraper:

                                       Rationnel(int x = 0, int y = 1) : mNum(x), mDen(y)
                                      {
                                          if (d == 0) {
                                              throw ExceptionConstructionRationnel();
                                          }
                                      }

                                      - la magie noire (parce que j'ai rien compris) qui consisterai a créer un variable `int non nulle`préalablement:

                                      template <typename T>
                                      struct striclty_positive {
                                          explicit striclty_positive(int i) n:(i)
                                          { assert(i > 0); }
                                          explicit operator int() const { return n };
                                      private:
                                          int n;
                                      };
                                       
                                      class Rational
                                      {
                                      public:
                                          Rational(int n, strictly_positive<int> d);
                                      ...
                                      };

                                      J'aimerai avoir plus de détail en particulier sur cette dernière méthode qui me semble très intrigante... Que je puisse choisir la "meilleur" méthode :(

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime.
                                        22 octobre 2018 à 14:49:55

                                        @romantik, peux-tu détailler s'il te plaît ? m'expliquer un peu plus ce que c'est que ce concept ?

                                        j'en ai déjà un peu entendu parler ici.

                                        Mais maintenant que j'ai fini le cours de Mateo21, je rentre dans le vif du sujet

                                        @Rymfire : oui, je trouve aussi la troisième méthode intéressante, avec son opérateur int(). j'ai aussi envie de comprendre

                                        en te remerciant

                                        -
                                        Edité par pseudo-simple 22 octobre 2018 à 14:53:17

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          22 octobre 2018 à 14:57:07

                                          @YES, man => FAQ de dvpz, beaucoup de choses y sont expliquées, ou alors le livre de Koala01.

                                          Par défaut, tout constructeur à un argument devrait être explicite, sauf si tu veux explicitement supporter une conversion -- cas de figure qui n'a de sens que sur les classes à sémantique de valeur.

                                          @Rymfire, lis les 3 billets sur la PpC sur mon blog. La magie noire y est aussi abordée au travers de `gsl::not_null`. Ici, en tout honnêteté, pour avoir tenté l'expérience (partagée sur le forum il y a 2 ans?), la notion de strictly_positive est très insuffisante: il faudrait aller plus loin, et c'est complexe à faire de façon ergonomique.

                                          En l'état, elle permet toutefois de forcer l'utilisateur à prendre conscience qu'un nombre positif est attendu, et à le forcer à prendre acte (casting, ou vérification dynamique).

                                          • 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.
                                            22 octobre 2018 à 15:02:31

                                            La dernière méthode n'a rien d'incroyablement particulier, elle déplace juste le contrôle de la valeur dans un type, sinon elle est équivalente à la première. Et c'est à mon sens celle qu'il faut préférer parce que c'est un contrôle dont on veut se débarrasser lorsque la validation du programme a été réalisée.

                                            Mais sinon, il n'y a rien de fou :

                                            template <typename T>
                                            struct striclty_positive {
                                                // un constructeur qui impose d'être demandé explicitement
                                                explicit striclty_positive(int i) n:(i)
                                                { 
                                                  // si l'entier fourni n'est pas strictement positif on 
                                                  // colle un assert dans la bouche de l'appelant.
                                                  assert(i > 0); 
                                                }
                                             
                                                // on fournit un opérateur pour "convertir" simplement
                                                // notre entier strictement positif en entier.
                                                explicit operator int() const { return n };
                                            private:
                                                int n;
                                            };

                                            Et du coup si on reçoit cet entier en entrée, on a la garantie qu'il est positif strictement et que l'on peut le transformer en entier.

                                            • Partager sur Facebook
                                            • Partager sur Twitter

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

                                              22 octobre 2018 à 17:25:18

                                              C'est l'inconvénient de poser des questions à des spécialistes, ils embrouillent tout avec des considérations subtiles et des mécanismes d'enfer qu'ils tiennent à montrer.

                                              Pour en revenir au problème : on a un constructeur, pendant la construction il y a quelque chose qui foire, on s'en rend compte alors qu'est ce qu'on fait ?

                                              Le cadre des fractions est un peu trop restreint, parce que

                                              • il n'y a qu'une seule raison pour laquelle ça peut merder (dénominateur incorrect)
                                              • on pouvait s'en rendre compte avant d'appeler le constructeur.

                                              Mais bon, "yakavépa appeler le constructeur", c'est pas une réponse généralisable.  Il est fréquent d'appeler un constructeur qui a besoin de faire, par exemple, une allocation dynamique pour un de ses membres, qui peut échouer pour des raisons X ou Y. Qu'est-ce qu'on fait ?

                                              Evidemment, il y a des cas où on peut plier le rideau par exit() ou assert().  Dans les programmes qui servent à rien. Mais bon, en général il y a des trucs à faire pour fermer la boutique proprement, et la réponse générique, c'est une exception.

                                              Et comme ça peut arriver dans la liste d'initialisation, y a même une syntaxe exprès.

                                              http://jsteemann.github.io/blog/2015/11/18/on-exception-handling/

                                              -
                                              Edité par michelbillaud 22 octobre 2018 à 17:26:37

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                22 octobre 2018 à 18:22:44

                                                michelbillaud a écrit:

                                                Pour en revenir au problème : on a un constructeur, pendant la construction il y a quelque chose qui foire, on s'en rend compte alors qu'est ce qu'on fait ?

                                                La réponse est simple : la logique est foireuse et doit être modifiée avant de passer en "production" / d'être envoyé à son prof.

                                                Logique (potentiellement) foireuse == assertion. Point Barre.  Cela se traduira forcément par un code proche de

                                                Fraction::Fraction(Type num, Type denom):
                                                    numerator_{num}, denominator_{denom}{
                                                    assert(denominator_!= 0 && "Null denominator detected");
                                                }

                                                Les exceptions, c'est pour les cas où une situation "à laquelle le développeur ne peut rien" risquerait -- justement -- de provoquer une erreur de logique.  Par exemple, l'extraction de données à partir d'un flux:

                                                std::isttream & operator >>(std::istream & ifs, Fraction & fr){
                                                    type tempenumerator;
                                                    type tempdenominator;
                                                    if(! ifs>>tempnumerator) { // oups... l'extraction foire
                                                        /* pas cool, parce que la suite foirera aussi
                                                         */
                                                        throw CannotGetEnumerator();
                                                    }
                                                    if(! ifs>>tempdenominator) { // oups... l'extraction foire
                                                        /* pas cool, parce que la suite foirera aussi
                                                         */
                                                        throw CannotGetDenominator();
                                                    }
                                                    if(tempdenominator == 0) { //l'extraction s'est bien passée
                                                        /* mais ca fera péter l'asseriton à l'étape suivante
                                                         * on ne peut donc pas laisser faire, mais on n'a
                                                         * aucun moyen d'y remédier
                                                         */
                                                        throw NullDenominator();
                                                    }
                                                    /* Oufff!!! arrivés ici, nous sommes en théorie certains
                                                     * d'avoir des données cohérentes
                                                     * 
                                                     * nous pouvons donc aller plus loin
                                                     */
                                                    fr = Fraction(tempnumerator, tempdenominator);
                                                    return ifs;
                                                }

                                                michelbillaud a écrit:

                                                Evidemment, il y a des cas où on peut plier le rideau par exit() ou assert().  Dans les programmes qui servent à rien. Mais bon, en général il y a des trucs à faire pour fermer la boutique proprement, et la réponse générique, c'est une exception.

                                                Non!

                                                La réponse générique se fait en deux temps :

                                                • ce qui est du ressort du développeur (de l'utilisateur) de la fonction se gère au travers d'une vérification des préconditions, et donc, au travers d'une assertion,
                                                • Ce qui n'est du ressort ni du développeur ni de l'utilisateur mais qui pourrait dégénérer en erreur de logique (et, par effet de rebond, faire péter une assertion) se gère au travers des exceptions.
                                                • 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
                                                  22 octobre 2018 à 18:30:12

                                                  Après, si on veut faire du code de SSII ...

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

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

                                                    23 octobre 2018 à 10:33:37

                                                    Pour moi une assertion ça s'utilise quand tu ne sais pas quoi mettre dans un catch.

                                                    Si tu peux rattraper le coup et insulter copieusement l'utilisateur en lui printant au passage une bonne cinquantaine de fois la raison pour laquelle tu viens de lui sauver le derrière, quoi de plus plaisant de le faire.
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      23 octobre 2018 à 10:42:32

                                                      LilyKianii a écrit:

                                                      Pour moi une assertion ça s'utilise quand tu ne sais pas quoi mettre dans un catch.

                                                      Je vois pas le rapport.

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

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

                                                        23 octobre 2018 à 11:00:27

                                                        koala01 a écrit:

                                                        michelbillaud a écrit:

                                                        Evidemment, il y a des cas où on peut plier le rideau par exit() ou assert().  Dans les programmes qui servent à rien. Mais bon, en général il y a des trucs à faire pour fermer la boutique proprement, et la réponse générique, c'est une exception.

                                                        Non!

                                                        La réponse générique se fait en deux temps :

                                                        • ce qui est du ressort du développeur (de l'utilisateur) de la fonction se gère au travers d'une vérification des préconditions, et donc, au travers d'une assertion,
                                                        • Ce qui n'est du ressort ni du développeur ni de l'utilisateur mais qui pourrait dégénérer en erreur de logique (et, par effet de rebond, faire péter une assertion) se gère au travers des exceptions.

                                                        Sachant que précisément, un constructeur qui ne peut pas faire ce qu'on en attend ne le signale pas, ça entraine forcément une "erreur de logique" dans le reste de l'application, qui n'est pas au courant. Ou alors c'est que le constructeur ne faisait rien d'utile...

                                                        Donc on est d'accord.

                                                        Mais y a un age où il faut dire "non", on est tous passés par là :-)

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          23 octobre 2018 à 11:03:40

                                                          michelbillaud a écrit:

                                                          Mais y a un age où il faut dire "non", on est tous passés par là :-)

                                                          Et j'imagine qu'il y a aussi un âge où on abandonne l'idée de vouloir éviter d'avoir des tests inutiles à l'exécution. J'imagine qu'on finit tous par passer par là aussi.

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter

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

                                                            23 octobre 2018 à 11:07:33

                                                            Ksass`Peuk a écrit:

                                                            LilyKianii a écrit:

                                                            Pour moi une assertion ça s'utilise quand tu ne sais pas quoi mettre dans un catch.

                                                            Je vois pas le rapport.

                                                            C'était trop imagé ? Grossièrement, tout ce que tu peux pas handle proprement, tu assert.

                                                            -
                                                            Edité par LilyKianii 23 octobre 2018 à 11:10:00

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              23 octobre 2018 à 11:09:32

                                                              michelbillaud a écrit:

                                                              Mais bon, "yakavépa appeler le constructeur", c'est pas une réponse généralisable.


                                                              Et pourquoi pas ?

                                                              C'est toute la philosophie de la PpC, et elle me convainc vraiment ! Je trouve les billets de lmghs vraiment intéressant.

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter
                                                              Dream on, Dream on, Dream until your dream comes true

                                                              Classe Fraction : le cas de la division par 0

                                                              × 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