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

Langage C++ Discussion :

Exception et retry


Sujet :

Langage C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut Exception et retry
    Bonjour,

    Une fois de plus je viens demander votre aide...
    Je suis en ce moment en train de developper une petite classe derivant de exception pour gerer les erreurs dans mon programme.

    Cependant j'aimerai creer une fonction membre de cette classe qui serait appelée dans le catch et qui me permettrait de gerer le traitement de cette erreur.
    Je voudrai pouvoir gerer 3 cas : creer une exception qui va relancer l'exception (throw(this)), creer une exception qui va continuer l'execution du programme (rien a faire dans ce cas, le programme continue apres le catch), et une autre qui va reessayer le code precedent (revenir dans le debut du try).

    Le comportement (les 3 cas) sera defini par une donnée membre (m_type) qui aura ete initialisé a une valeur lors de la creation de l'objet exception.

    bref, ca donne quelque chose comme ca :

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    #include <iostream>
    #include <sstream>
    #include <exception>
     
     
    #define EXC_CONTINUE	1
    #define EXC_ABORT	2
    #define EXC_ASK		3
     
     
    class CMyException : public exception
    {
        private:
     
    	short m_type;
     
        public:
     
    	CMyException(const string message, const short type=EXC_ASK)
    	:m_type(type)
    	{
    		std::ostringstream oss;
    		oss << "ERROR : " << message;
    		msg = oss.str();
    	}
     
     
     
    	virtual ~CMyException() throw()
    	{}
     
    	virtual const char* what() const throw()
    	{
    		return msg.c_str();
    	}
     
    	void eval()
    	{
    		switch(m_type)
    		{
    			case EXC_CONTINUE:
    				break;
     
    			case EXC_ABORT:
    				throw(this);
     
    			case EXC_RETRY:
    				// ???
    				break;
     
    			case EXC_ASK:
    				// a faire
    				break;
     
    		}
    	}
     
    	int getType() { return m_type; }
     
    	void setType(int type) { m_type=type; }
     
    };
    Voila, le probleme vient de la fonction eval... Je ne sais deja pas si elle a quelque chose a faire dans la classe CMyException...
    Ensuite je ne suis pas sur de sa pertinence notamment pour le cas retry que je ne sais pas du tout gerer... Il me faudrait un moyen de retourner dans le try... une fonction retry...
    Ou alors un goto... non c'est pour rire c mal le goto mais il y a surement un defaut de conception derriere tout ca et je ne sais pas trop comment gerer ca...

    Si vous avez un indice ca serait super merci !!!

    @ bientot.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut
    Une boucle contenant le try catch controlée par un boolen qui serait modifié (passage par adresse) lors de la fonction eval... ?
    Ca parait tordu mais il se fait tard...

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #define EXC_CONTINUE	1
    #define EXC_ABORT	2
    #define EXC_ASK		3
    Tu connais les enum ou au - les constantes ?
    Sinon, je pense que ton défaut de conception est de vouloir mettre dans l'exception une partie de son traitement. Ce que tu veux faire devrait être fait dans le traitement de l'exception et non par l'exception.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut
    Ok les enums je m'y met pas bete ! Merci pour le conseil... j'apprends.

    D'accord donc d'apres toi ca ne sert a rien que j'essaye d'encapsuler cela dans mes propres methodes (et surtout pas dans mon exception) et il vaut mieux faire ca traditionnellement au cas par cas (des try catchs avec du code dedans quoi )... Je pense laisser tomber la fonction "quifaittout"...

    Je me demandais surtout si il y avait un schema classique pour faire un retry ou pour arriver a faire ce que j'essaye de faire avec ma fonction... Une piste ?

    Merci.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Un schéma un peu crade mais qui fonctionne pourrait être
    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
    void foo()
    {
        /* ce qui ne doit être fait qu'une fois au début */
        begin:
        try
        {
             laFonctionQuiRisqueDeRater();
        }
        catch(MonException & e)
        {
            /* gestion de l'erreur */
            goto begin;
        }
        /* ce qui ne doit être fait qu'une fois à la fin */
    }
    Si je dis que le schéma est un peu crade, c'est à cause de la présence du goto... que l'on cherche généralement à éviter autant que possible.

    Il existe donc une solution plus "propre" qui utiliserait les boucles sous une forme proche de
    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
    void foo()
    {
        /* ce qui ne doit être fait qu'une fois au début */
        bool again=false; /* on considère que la première fois marchera */
        do
        {
            try
            {
                 laFonctionQuiRisqueDeRater();
            }
            catch(MonException & e)
            {
                /* gestion de l'erreur */
                /* si on arrive ici, il faut recommencer... */
                again = true;
            }
        }while(again==false);
        /* ce qui ne doit être fait qu'à la fin */
    }
    mais qui ajoute un niveau d'indentation...

    Si la logique à effectuer dans la boucle est elle-même déjà complexe et nécessite plusieurs niveaux d'indentation, le code effectif risque de finir par se retrouver "dans les matitis"
    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

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut
    Ok, je te remercie pour ce bout de code, ca correspond a peu pres a ce que je pensais faire.
    Je vais essayer de voir si je peux me faire une fonction qui me permet de faire ca de facon transparente.

    D'ailleurs ca m'a mené a discuter avec un ami du probleme du goto... Si on met l'etiquette dans le try au tout debut, que va-t-il se passer a l'execution ? Le programe "saura"-t-il qu'il est dans le bloc try ? plantage ?

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Bouteille Voir le message
    Ok, je te remercie pour ce bout de code, ca correspond a peu pres a ce que je pensais faire.
    Je vais essayer de voir si je peux me faire une fonction qui me permet de faire ca de facon transparente.

    D'ailleurs ca m'a mené a discuter avec un ami du probleme du goto... Si on met l'etiquette dans le try au tout debut, que va-t-il se passer a l'execution ? Le programe "saura"-t-il qu'il est dans le bloc try ? plantage ?
    Ca, c'est une bonne question...

    J'aurais tendance à dire que le compilateur risque de ne pas se rendre compte qu'il est dans le bloc try et que cela occasionnera donc au mieux un plantage...

    Etant, à titre personnel, loin d'être un ardent défenseur du goto, j'avouerai sans honte souvent préférer une solution basée sur une boucle et n'avoir proposé la version à base de goto que parce qu'elle est finalement la plus simple à mettre en oeuvre

    Mais l'utilisation du goto est un autre débat, qui est loin d'être tranché
    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

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut
    Oui oui je suis d'accord avec toi pour ce qui est de preferer la solution a base de while plutot que de goto...

    Merci pour les reponses alors... Je pense que je peux marquer resolu et retourner a mon labeur

    @ bientot...

    Et si certains ont un avis sur ce qui se passe avec le goto dans le try ca m'interresse aussi

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    La vrai question est qui doit décider de la politique à suivre (recommencer, continuer, propager l'exception ou demander à l'utilisateur).
    On a trois acteurs dans cette relation : celui qui lève l'exception (l'appelé), l'exception levée et celui qui récupère l'exception (l'appelant).
    Ce n'est clairement pas l'exception qui n'est là 'que' pour transporter l'erreur.
    Ce n'est pas l'appelé : par définition, les exceptions ont pour but de déléguer la gestion de l'erreur vers l'appelant et éviter d'avoir à l'appelé à prendre des décisions qui ne sont pas de son ressort. Donc, ce n'est clairement pas là qu'il faut prendre cette décision.
    Reste l'appelant. Or sur quel critère va-t-il prendre la décision de recommencer, continuer, propager ou demander à l'utilisateur ? C'est en répondant à cette question que tu trouveras certainement la conception la plus appropriée.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut
    C'est vrai que j'ai tendance a voir le probleme a l'envers dans ce cas la en donnant la responsabilité de choisir de l'eventuelle repropagation de l'erreur au moment de la creation de l'exception (donc au niveau de l'appelé)...

    Je pense que je vais devoir reflechir un peu plus aux cas concrets ou je vais l'utiliser pour me mettre en situation parce que j'ai voulu concevoir cela sans vraiment penser aux differents cas de figures possibles...

    Des news bientot.

    PS : mais une petite fonction standard retry a appeler dans le catch ca aurait ete sympa quand meme pour relancer le try bref ca doit surement poser plus de problemes que de solutions sinon d'autres y auraient pensé

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Bouteille Voir le message
    C'est vrai que j'ai tendance a voir le probleme a l'envers dans ce cas la en donnant la responsabilité de choisir de l'eventuelle repropagation de l'erreur au moment de la creation de l'exception (donc au niveau de l'appelé)...

    Je pense que je vais devoir reflechir un peu plus aux cas concrets ou je vais l'utiliser pour me mettre en situation parce que j'ai voulu concevoir cela sans vraiment penser aux differents cas de figures possibles...
    Feuillètes un livre ou un tuto un peu général (ici pour le C++ et ici pour de la conception). Faut pas hésiter à les revoir de temps en temps.

    Citation Envoyé par Bouteille Voir le message
    PS : mais une petite fonction standard retry a appeler dans le catch ca aurait ete sympa quand meme pour relancer le try bref ca doit surement poser plus de problemes que de solutions sinon d'autres y auraient pensé
    Tu pourrais t'en sortir avec la récusivité si tu es sûr de maîtriser la profondeur :
    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    #include <iostream>
    #include <exception>
     
    void fonction()
    {
       throw std::exception();
    }
     
    template<int Nbr, typename OpT>
    struct TryCatch_impl
    {
       static void DoIt(OpT op)
       {
          try
          {
             op();
          }
          catch(std::exception &ex)
          {
             std::cout<<ex.what()<<std::endl;
             TryCatch_impl<Nbr-1,OpT>::DoIt(op);
          }
       }
    };
     
    template<typename OpT>
    struct TryCatch_impl<0,OpT>
    {
       static void DoIt(OpT op)
       {
          // l'exception sera traité plus haut
          op();
       }
    };
     
    template<int Nbr, class OpT>
    void TryCatch(OpT op)
    {
       TryCatch_impl<Nbr,OpT>::DoIt(op);
    }
     
     
    int main(){
       try{
          TryCatch<3>(fonction);
       }
       catch(std::exception &)
       {
          std::cout<<"Toujours pas !"<<std::endl;
       }
        return 0;
    }

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut
    Wow pas mal je n'aurais jamais pensé a quelque chose de la sorte...

    Il faut encore que je lise un peu de doc comme tu me l'a conseillé et que je digere ton exemple mais ca m'a l'air plutot sympa...
    Reste a voir si c'est adaptable et si ca vaut le coup pour l'utilisation que je vais en faire.

    En tout cas c'est super interressant de parler avec vous... Ca donne envie d'aller plus loin.

    Juste encore une question de newbie... pourquoi statique la fonction DoIt... et pourquoi dans une struct ? c'est la contrainte pour pouvoir utiliser les templates ? je ne suis aps familier des templates mais je vais aller voir la doc...
    D'instinct j'aurais fais des fonction membres d'une classe ou alors carrement des fonctions libres...

    Merci !!!

  13. #13
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Bouteille Voir le message
    pourquoi statique la fonction DoIt... et pourquoi dans une struct ? c'est la contrainte pour pouvoir utiliser les templates ? je ne suis aps familier des templates mais je vais aller voir la doc...
    La fonction est statique car elle est dans une struct et qu'il n'y a pas d'intérêt à instancier la structure.
    La fonction est encapsulée dans une structure car on ne peut pas faire de spécialisation partielle avec une fonction template alors qu'avec une structure oui. Et on n'a besoin d'une spécialisation partielle pour terminer la 'méta-boucle' :
    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
     
    template<int nbrIt, typename OpT>
    void DoIt(OpT op)
    {
    // ....
    }
    template<typename OpT>
    void DoIt<0,OpT>(OpT op) // ne compile pas
    {
    // ....
    }
     
    template<int Nbr, typename OpT>
    struct TryCatch_impl
    {
    //[...]
    };
     
    template<typename OpT>
    struct TryCatch_impl<0,OpT> // Ok
    {
    //[...]
    };
    Citation Envoyé par Bouteille Voir le message
    D'instinct j'aurais fais des fonction membres d'une classe ou alors carrement des fonctions libres...
    Je ne connais pas ton problème spécifique, mais je soupçonne qu'une approche générique soit intéressante. Car, à la limite tu veux définir un comportement probablement indépendamment de la méthode appelé et plus ou moins de l'exception levée. Je te conseille cet article qui pourra t'inspirer quelques idées : Présentation des classes de Traits et de Politiques en C++, de Alp

  14. #14
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Bouteille Voir le message
    En tout cas c'est super interressant de parler avec vous... Ca donne envie d'aller plus loin.

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut
    Super explications !! Merci bcp !

    Le lien sur les classes de trait m'ouvre carrement un nouveau monde aussi

    Je reviens dans peu de temps pour vous presenter la solution choisie au final...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XMLRAD] gestion des exceptions
    Par pram dans le forum XMLRAD
    Réponses: 2
    Dernier message: 28/01/2003, 17h48
  2. Exception & Try..catch
    Par PurL dans le forum C++Builder
    Réponses: 2
    Dernier message: 11/12/2002, 15h35
  3. Réponses: 3
    Dernier message: 01/11/2002, 14h30
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. c: gestion des exceptions
    Par vince_lille dans le forum C
    Réponses: 7
    Dernier message: 05/06/2002, 14h11

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