IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

question sur les throw catch


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut question sur les throw catch
    Bonjour

    J'ai une question de base sur les gestions d'erreurs. Je ne comprends pas pourquoi le code suivant fonctionne:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    int f(int i) {
       throw "test";
       return 0;
    }
     
    class C {
       int i;
     
    public:
       C(int);
    };
     
    C::C(int ii) {
       try {   // function-try block
          f(ii) ;
          // body of function goes in try block
       }
       catch (...) {
          // handles exceptions thrown from the constructor-initializer
          // and from the constructor function body
          printf_s("In the catch block\n");
       }
    }
     
    int main() {
       C *MyC = new C(0);
       delete MyC;
    }

    alors que celui là, où j'ai juste remplacé catch(...) par catch(char*),

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    int f(int i) {
       throw "test";
       return 0;
    }
     
    class C {
       int i;
     
    public:
       C(int);
    };
     
    C::C(int ii) {
       try {   // function-try block
          f(ii) ;
          // body of function goes in try block
       }
       catch (char*) {
          // handles exceptions thrown from the constructor-initializer
          // and from the constructor function body
          printf_s("In the catch block\n");
       }
    }
     
    int main() {
       C *MyC = new C(0);
       delete MyC;
    }
    ne fonctionne pas.

    Je pensais que throw renvoyait une exception de type char*, mais, bien que cette exception se situait à un niveau plus inférieur que catch(char*), celle-ci remonterait pour être attrapée par ce catch. Mais ce n'est pas le cas apparemment.

    Pourriez vous m'expliquer pourquoi?

    Il semble que catch(...) soit un catch par défaut.


    Merci

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,
    J'obtiens :
    cas n°1 : "In the catch block"
    cas n°2 : "In the catch block"

    Pas trop compris ce que tu voulais montrer ?

    PS : L'exemple est un peu curieux d'ailleurs. Pourquoi intercepter l'exception dans le constructeur et faire croire que tout c'est bien passé ? Généralement si la construction d'une classe échoue, on lance une exception vers l'extérieur pour signaler le problème, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    int f(int i) 
    {
       throw "test";
       //return 0; return optionel ici
    }
     
    class C 
    {
       int i;
     
    public:
       C(int ii)
       {
          f(ii) ;
       }
    };
     
     
    int main() 
    {
       C* MyC = NULL;
     
       try 
       {   
          MyC = new C(0);
       }
       catch (char*) 
       {
          // handles exceptions thrown from the constructor-initializer
          // and from the constructor function body
          printf_s("In the catch block\n");
          // delete MyC; pas besoin de delete ici
       }
    }

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    1- l'ellipse "(...)" récupère "n'importe quelle exception", c'est à dire, toute exception non rattrapée par ailleurs

    2- ce n'est pas catch "(char * c)" que tu aurais du écrire mais "const char * c", car le pointeur est constant

    3- +1 avec Azar... A moins que tu ne puisse faire quelque chose quand une exception est lancée, il ne sert pas à grand chose de la récupérer (et surtout de ne pas la relancer): le système se trouve dans un état aberrant lorsqu'une une exception est lancée. le but du catch est de te donner l'occasion de replacer le système dans un état correct . Tant que l'exception n'a pas pu être totalement gérée, il est donc largement recommandé de la laisser remonter, dans l'espoir qu'une des fonctions appelantes (de manière directe ou indirecte) puisse assurer cette remise du système dans un état correct

    4- Il est très largement préférable de lancer des exception prenant la forme d'objets (de les lancer par valeur et de les récupérer par référence, pour être précis). En effet, le but premier d'une exception est, bien sur, de signaler que "quelque chose cloche", mais, surtout, de transmettre une information sur le contexte dans lequel cette chose à cloché.

    Si tu ne transmet qu'une chaine de caractères (ou une valeur numérique entière) comme exception, tu te place dans une situation dans laquelle tu dois systématiquement tester l'ensemble des valeurs que les différentes exceptions peuvent prendre, ce qui peut rapidement devenir un foutoir sans nom.

    Si, par contre, tu transmet des classes ou des structures, même si elles sont vide (à l'exception d'une fonction "what"), tu peux beaucoup plus facilement gérer les différents cas de figures, y compris grâce aux éventuelles hiérarchies de classes existantes, en plus de te permettre de fournir des informations plus précises sur ce qui a provoqué le problème

    PS: d'ailleurs, l'idéal est toujours de d'hériter d'une des classes d'exception fournies par le standard, en choisissant celle qui correspond le mieux au contexte "générique" dans lequel le problème est survenu
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    moi, quand je lance le deuxième cas, j'ai le message d'erreur suivant:

    mais effectivement, quand je remplace par const char*
    cela fonctionne parfaitement.

    L'exemple est tiré de la MSDN
    Images attachées Images attachées  

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par deubelte Voir le message
    moi, quand je lance le deuxième cas, j'ai le message d'erreur suivant:

    mais effectivement, quand je remplace par const char*
    cela fonctionne parfaitement.

    L'exemple est tiré de la MSDN
    C'est normal...

    Tu essaye d'attraper un const char * avec un catch( char*), ce qui fait que l'exception n'est pas attrapée.

    Comme tu n'a pas d'autre catch qui soit éventuellement en mesure de récupérer ton exception, elle n'est... jamais récupérée et provoque la fin de l'application.

    Et le système te signale que l'application est quittée parce qu'une exception n'a pas été attrapée
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Question sur les exceptions catch / non catch
    Par MrEddy dans le forum Général Java
    Réponses: 2
    Dernier message: 21/10/2010, 12h25
  2. question sur les vertex buffer et index buffer
    Par airseb dans le forum DirectX
    Réponses: 9
    Dernier message: 25/08/2003, 02h38
  3. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59
  4. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo