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 :

Corriger le traitement aprés une Exception


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Corriger le traitement aprés une Exception
    Bonjour,

    Je réalise actuellement un programme pour multiplier deux matrices. Les éléments des matrices sont stockées dans un vecteur.
    J'ai donc une classe Matrix qui hérite de la classe Vector.

    J'arrive deja à controler le type des éléments entrés au clavier et je sors du programme proprement lorsqu'une exception est générée lors des entrées au clavier.

    J'ai donc un bloc comme ça dans mon main:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    try {
    ...........
    }
    catch {
    std::cout << ......;// message à l'écran lorsqu'une exception est générée
    exit(-1);// je sors completement du programme....
    }
    Donc je souhaite savoir s'il est possible, au lieu d'avoir un exit(-1) qui me fait sortir complétement du programme, de revenir dans la méthode qui a lancé l'exception et demander à l'utilisateur de rentrer une valeur correct pour l'entrée qui n'est pas bonne (ou de recommencer l'entrée de la matrice).
    Ca me serait utile pour l'entrée des termes de la matrice au clavier.

    Je souhaite aussi savoir si j'ai besoin d'un destructeur pour ma classe Matrix qui hérite de Vector (qui lui a un destructeur).

    Merci d'avance pour votre réponse .

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Une exception C++ ne "redescend" pas dans la fonction qui l'a lancée.
    Mais tu peux toujours faire une boucle de ce genre:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bool ok = false;
    do {
    	try {
    		fonction();
    		ok = true;
    	} catch(truc &) {
    		//...
    	}
    } while(!ok);

  3. #3
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Dans ce cas là autant faire :

    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
    bool fonction ( int & retour_utilisateur )
    {
      // demande à l'utilisateur de saisir un truc
     
      if ( controles de validite pas remplit )
        return false;
     
      return true;
    }
     
     
    int main()
    {
      int retour_utilisateur;
     
      while ( !fonction( retour_utilisateur ) )
        ;
     
      // retour_utilisateur est correct ici
    }
    Faire appel au exceptions dans le flow normal de l'application, on m'a toujours dit que c'était mal. De plus l'exception doit refléter une erreur de programmation, un cas auquel on a pas pensé.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Non, l'exception, ça peut être bien pour toute erreur qui interompt le traitement.
    Mais en effet, l'exception ne doit pas arriver en fonctionnement "normal", car ça coûte cher.

    Pour moi, des données invalides comptent comme une erreur justiviant une exception. Surtout si lesdites données sont lues d'un fichier.

  5. #5
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Dans ce cas là autant faire :

    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
    bool fonction ( int & retour_utilisateur )
    {
      // demande à l'utilisateur de saisir un truc
     
      if ( controles de validite pas remplit )
        return false;
     
      return true;
    }
     
     
    int main()
    {
      int retour_utilisateur;
     
      while ( !fonction( retour_utilisateur ) )
        ;
     
      // retour_utilisateur est correct ici
    }
    Faire appel au exceptions dans le flow normal de l'application, on m'a toujours dit que c'était mal. De plus l'exception doit refléter une erreur de programmation, un cas auquel on a pas pensé.
    On t'as dit des choses méchantes. Malgré le nom, une exception est un générée suit à un traitement anormal, pas suite à une condition exceptionnelle. Cf vector<>::at() (l'indice passé peut être calculé dynamiquement).

    Quand au problème soulevé par notre posteur originel, il est du au fait que le système d'entrée peut générer des exceptions. Il convient donc de les traiter correctement. La solution de Médinoc est tout à fait acceptable (ce qui ne veut pas dire que la tienne ne l'est pas).

    En ce qui concerne les desructeurs, une règle simple à respecter :
    * si une classe peut se passer de constructeur, alors elle peut se passer de desructeur.
    A toi de voir si c'est le cas

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Sauf que je ne suis pas d'accord avec cette règle.
    Dans beaucoup de classes utilisées pour des objets temporaires, c'est le destructeur qui est important, pas le constructeur.

    (même si en pratique, on a quand même au moins besoin d'initialiser les valeurs, même si on ne fait le "vrai" travail que dans une fonction séparée...)

  7. #7
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Quand au problème soulevé par notre posteur originel, il est du au fait que le système d'entrée peut générer des exceptions. Il convient donc de les traiter correctement.
    Je comprends. C'est vrai je n'y avait pas pensé.

    De plus l'exception doit refléter une erreur de programmation, un cas auquel on a pas pensé.
    Par contre là, je voulais plutôt dire "un cas que l'on ne gère pas".

  8. #8
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    De plus l'exception doit refléter une erreur de programmation, un cas auquel on a pas pensé.
    Ca, c'est le rôle des assertions.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par gatua Voir le message
    J'ai donc une classe Matrix qui hérite de la classe Vector.
    Curieux... Un vecteur est un cas particulier de matrice, pas l'inverse.

    Lorsque tu fais ton héritage dans ce sens-là, la classe plus spécialisée offre des garanties moins fortes. Ca devrait être l'inverse. C'est le principe de Liskov, qui veut qu'une propriété du type de base s'applique aussi au type dérivé.

    Exemple: ton type de base, Vector, a une propriété forte: il n'a qu'une seule colonne ou qu'une seule ligne. Ce n'est pas vrai pour une matrice. Bigbadaboum.

    Carl

  10. #10
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Pour moi, le principal intérêt des exceptions, c'est qu'une exception générée dans ton code remonte et peut être attrapée dans le code écrit par quelqu'un d'autre. Ce qui n'est pas faisable avec des valeurs de retour... (ou pas aussi simple)

  11. #11
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Quand on a des situations non nominales qui surviennent (rupture connexion réseau, données invalides, disques pleins, ...), même dans son propre code, c'est l'approche à retenir.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    Merci à tous pour vos réponses.

    J'ai donc incorporé ceci dans mon main:

    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
    int main()
    {
    bool ok = false;
     
    do {
     
            try {
               // Création des deux objets de type Matrix
               // Entrée de la Matrice 1 au clavier
              //  Lecture de la Matrice 2 dans le fichier
              // Création d'un objet de type Matrice (Matrice 3)
              // Multiplication: Matrice 3 = Matrice 1 * Matrice 2
              // Affichage de la Matrice 3 à l'écran
              ok =true;
           }
           catch (Exceptbidule& bd) {
                  std::cout << ........;
            } 
    } while (!ok);
     
    return 0;
     
    }
    J'ai un problème car lorsqu'une exception est générée, une boucle infinie est générée. La raison est que les objets de type Matrice (Matrice 1 et Matrice 2)
    ne sont pas effacés et du coup les valeurs incorrects sont conservées.
    Seule ma classe Vector a un destructeur.

    De plus, je voudrais savoir si vous avez une manière plus élégante que celle ci pour faire un controle pour chaque étape principale, c'est à dire avec un code de ce genre:

    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
    int main()
    {
    bool ok1 = false;
    bool ok2 = false;
    bool ok3 = false;
    .
    .
    .
     
    do {
     
            try {
               // Création des deux objets de type Matrix
              ok1 =true;
           }
           catch (Exceptbidule& bd) {
                  std::cout << ........;
     
            } 
    } while (!ok1);
     
    do {
     try {
               // Entrée de la Matrice 1 au clavier
             ok2 =true;
           }
           catch (Exceptbidule& bd) {
                  std::cout << ........;
            } 
    } while (!ok2);
     
    do {
     try {
               // Entrée de la Matrice 1 au clavier
              ok3 =true;
           }
           catch (Exceptbidule& bd) {
                  std::cout << ........;
            } 
    } while (!ok3);
    .
    .
    .
    .// Blocs similaires pour les autres étapes
    .
    .
     
    return 0;
     
    }

  13. #13
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Points en vrac :

    Le critère "normal" pour déterminer s'il vaut mieux utiliser un retour de fonction ou une exception m'a toujours semblé subjectif et vaseux. J'utilise plutôt le suivant : Sachant qu'une exception a pour but de propager une erreur entre son point de détection et son point de traitement, si la distance est nulle ou faible, code de retour, si elle est grande, exception.

    Pour les destructeur, il est courant qu'une classe de base abstraite n'ait pas de constructeur, par contre, il est souvent utile dans ce genre de cas qu'elle ait un destructeur (vide, mais déclaré quand même pour qu'il soit virtuel).

    Pour le problème de boucle après erreur : Une erreur dans la lecture clavier va invalider cin. Il faut lui reseter ses flags d'erreur avant de pouvoir reprendre toute lecture. C'est peut-être lié à ça.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    En fait, la boucle infinie a été réglé en rajoutant ceci dans le catch:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
           cin.clear(); 
           cin.ignore( numeric_limits<streamsize>::max(), '\n' );
    Quelqu'un a une idée pour ma deuxième question concernant le controle de chaque bloc d'instruction principal (Saisie au clavier de la Matrice 1, Lecture de la Matrice 2, ...)?
    C'est à dire ne pas etre obligé de tout refaire mais revenir directement à la partie ou une erreur a été faites.

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

Discussions similaires

  1. Reprise d'une boucle après une exception
    Par MaInR0 dans le forum PL/SQL
    Réponses: 2
    Dernier message: 22/12/2008, 17h08
  2. Traitement d'une exception
    Par Sebastien_INR59 dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 11/11/2007, 20h29
  3. Comment continuer un pgr apres une exception ?
    Par stan314 dans le forum Général Python
    Réponses: 1
    Dernier message: 30/09/2007, 18h03
  4. Réponses: 1
    Dernier message: 11/10/2006, 16h24
  5. Réponses: 6
    Dernier message: 28/08/2006, 17h02

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