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

Contribuez C++ Discussion :

exceptions.h, vers une gestion plus facile des exceptions


Sujet :

Contribuez C++

  1. #1
    Candidat au Club
    Profil pro
    Chercheur en informatique
    Inscrit en
    Juin 2004
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Juin 2004
    Messages : 3
    Par défaut exceptions.h, vers une gestion plus facile des exceptions
    Il peut être un peu pénible de tracer rapidement d'où vient une exception, notamment du fait que les informations sur l'emplacement de sa déclaration ne sont pas immédiatement accessibles.

    Bien sûr, on peut facilement récupérer ce contexte en utilisant le débogueur, mais cela reste difficile pour de simples utilisateurs. Un bon compromis est d'ajouter une forme de lien vers le code source directement dans le message, facile à copier/coller.

    C'est ce que propose cette très (très) léger outils : exceptions.h. Il permet d'inclure très facilement le nom de la fonction, le fichier et le numéro de ligne d'où provient l'exception, tout en facilitant leur usage (déclaration et instanciation).

    Par exemple, ce code :
    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
     
    #include <iostream>
    #include <iomanip>
     
    #include "exceptions.h" 
     
    // Une macro permet de faciliter la création d'une hiérarchie d'exceptions
    EXCEPTION( Exception, Observation_Existentielle );
        EXCEPTION( Observation_Existentielle, Observation_Bouddhiste );
            EXCEPTION( Observation_Bouddhiste, Observation_Zen );
        EXCEPTION( Observation_Existentielle, Observation_Pastafariste );
     
    int main()
    {
        try {
            double pi = 3.1415926535;
            // Une autre macro permet de facilement lever une exception avec un message construit dynamiquement
            RAISE( Observation_Pastafariste, std::setprecision(3) << "Les emmerdes, ça arrive avec " << pi << " appendices nouillesques" );
        } catch( Observation_Existentielle & e ) {
            std::cerr << e.what() << std::endl;
        }
    }
    Affichera :
    Les emmerdes, ça arrive avec 3.14 appendices nouillesques (<Observation_Pastafariste> in main at example.cpp:18)

    Explications

    Déclaration

    La classe de base utilisée pour mettre en place la hiérarchie hérite de std::exception, et utilise l'interface what, plus ou moins de la même manière que std::runtime_error et std::logical_error.

    La macro EXCEPTION(Observation_Existentielle, Observation_Pastafariste );, permet de déclarer en une seule ligne (il en faudrait beaucoup plus sans) l'exception Observation_Pastafariste comme dérivant de Observation_Existentielle. Ainsi, si vous interceptez des instances de la classe Observation_Existentielle, vous intercepterez une instance de la classe Observation_Pastafariste.

    Localisation

    Pour ajouter les informations sur l'endroit d'où provient l'exception, on utilise les macros __FUNCTION__, __FILE__ et __LINE__, qui sont gérées par le compilateur lui-même. La classe Exception permet de les passer au constructeur (soit directement, soit à l'aide d'une autre macro plus courte : E_INFOS), vous pourriez par exemple faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    throw Observation_Existentielle( "Les emmerdes, ça arrive", E_INFOS );
    Utilisation

    Pour faciliter encore un peu plus l'emploi de cette construction, une dernière macro permet d'inclure automatiquement toutes ces informations, sans avoir à les taper :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RAISE( Observation_Zen, "Quel est le son des emmerdes qui arrivent ?" );
    Et y ajoute la possibilité d'utiliser un message à base de flux, sans avoir à le déclarer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RAISE( Observation_Bouddhiste, "Il y a" << 0 << " emmerdes qui arrivent, en réalité." );
    À comparer avec la version que vous devriez taper, sans exceptions.h :
    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
     
    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <sstream>
    #include <stdexcept>
     
    class Observation_Existentielle : public std::runtime_error
    { public:
        Observation_Existentielle( const std::string & what_arg ) : std::runtime_error(what_arg) {}
    };
     
    class Observation_Bouddhiste : public Observation_Existentielle
    { public:
        Observation_Bouddhiste( const std::string & what_arg ) :Observation_Existentielle(what_arg) {}
    };
     
    int main()
    {
    try {
            std::ostringstream msg;
            double vacuite = 0;
            // Notez que le nom de l'exception est codé en dur et doit être maintenu 2 fois...
            msg << "Il y a " << vacuite << " emmerdes qui arrivent (<Observation_Bouddhiste> in " << __FUNCTION__ << " at " << __FILE__ << ":" << __LINE__ << ")";
            // Sans oublier la conversion en string.
            throw( Observation_Bouddhiste( msg.str() ) );
     
        } catch( Observation_Existentielle & e ) {
            std::cerr << e.what() << std::endl;
        }
    }

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 146
    Billets dans le blog
    4
    Par défaut
    Salut,

    personnellement j'aime bien les macros et cette utilisation, j'adhère au concept.
    Mais des exceptions en C++ j'en génère très très peu (aucune en fait je crois), je préfère travailler avec des codes d'erreur.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. Réponses: 20
    Dernier message: 30/08/2012, 11h35
  2. [Outils][C#/API Tapi] Y a-t-il une gestion du nombre des appels ?
    Par andreaslecousin dans le forum EDI/Outils
    Réponses: 7
    Dernier message: 16/03/2007, 15h08
  3. comment faire une redirection vers une page qui contient des framsets
    Par zana74 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 31/08/2006, 13h03
  4. Réponses: 9
    Dernier message: 19/10/2005, 04h35
  5. [Tomcat] migration vers une version plus récente
    Par butcher dans le forum Tomcat et TomEE
    Réponses: 4
    Dernier message: 31/10/2003, 21h46

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