6
votes

Comment éviter d'écrire un code répété dans des blocs de capture?

J'utilise Qt 4.8 (C ++) pour le projet d'application de bureau et écrivez une manipulation d'exception, comme suit:

void callerMethod()
{
  try
  {
   method1();
  }
  catch(Exception1& e)
  {
    // display critcal error message
    // abort application
  }
  catch(std::Exception& e)
  {
   // print exception error message
  }
  catch(...)
  {
   // print unknown exception message
  } 
}

void method1()
{
  try
  {
   // some initializations
   // some operations (here exceptions can occur)
   // clean-up code (for successful operation i.e no exception occurred)
  }
  catch(Exception1& e)
  {
   // clean-up code
   throw e;
  }
  catch(Exception2& e)
  {
   // clean-up code
   throw e;
  }
  catch(Exception3& e)
  {
   // clean-up code
   throw e;
  }
  catch(...)
  {
   // clean-up code
   throw;
  }
}


3 commentaires

Essayez de réduire la quantité de code de nettoyage nécessaire en utilisant des pointeurs intelligents, des classes de conteneurs, etc. Idéalement, il ne devrait pas y avoir de code de nettoyage du tout.


Il semble que ce que vous voulez faire est simplement essayer {/ * peut lancer * /} catch (spécifique_exception const & e) {/ * terminer * /} . Si vous ne vous souciez pas des types d'exception Exception1 , EXCEPTION2 et ainsi de suite, puis NE PAS les attraper.


De plus, même si vous prenez la référence par référence, vous devriez Rethrow à l'aide de à lancer; au lieu de lancer e; pour éviter la découpe.


3 Réponses :


8
votes

Méthode1 peut être très simplifié par deux concepts:

  1. Raii . Mettez tout code de nettoyage dans les destructeurs et le code de nettoyage sera centralisé.
  2. Utilisez le jet non qualifié et vous n'avez pas besoin de savoir sur le type d'exception lancé.

    donc, méthodétique1 () devrait ressembler à: xxx

    Le premier Catch CallerMethod peut être supprimé si vous dérivez une exception1 à partir de std :: exception , puisque le what () est virtuel.


5 commentaires

Mais je veux gérer Exception1 séparément à Calternerthod (). Si Exception1 s'est produite, je veux abandonner l'application.


@Anwarshaikh: Vous pouvez toujours le faire. Raii résout votre problème de nettoyage uniquement.


D'accord. j'ai compris!! Capture unique (STD :: Excepte & E) et utiliser quoi () Je pense que je peux obtenir le type d'exception. Et je ne suis pas au courant de Raii, il semble que cela résoudra mon problème de nettoyage. Je vais enquêter à ce sujet. Toute lien de ressource de bonne ressource pour Raii vous aidera. Merci .. Thiton et Nawaz.


@Anwarshaikh: ont lié à un tutoriel approprié.


@Anwarshaikh: vous pouvez lire Raii idiom ici qui l'a expliqué dans court. Et Cet article a une longue explication.



0
votes

Si tout votre code de nettoyage est totalement identique, vous pouvez tout faire dans votre bloc de capture (...): xxx

si votre code varie légèrement, vous pouvez toujours appeler un nettoyage Fonction: xxx


1 commentaires

Si j'écris une capture unique (..) qui transmet une exception alors, dans la méthode de l'appelant, comment saurai-je que cette exception a eu lieu. Parce que je veux gérer Exception1 qui abandonnent l'application.



1
votes

Vous devez lancer des exceptions aussi bas que possible et les attraper le plus haut possible dans la chaîne d'appels. Cela conduit automatiquement à moins de duplication de code et centralise la manipulation des erreurs. Vous lancez / attrapez tout au même endroit, qui semble un peu ... forcé.

Je fais souvent ce genre de chose (surtout pour les exceptions de fin de programme: P>

int main()
try
{
    function_calls_that_may_throw();
    // ...
}
catch(my_exception& e)
{
    e.do_exception_stuff();
}
catch(std::exception& e)
{
    std::cout << e.what();
}
catch(...)
{
    std::cout << "Something bad happened.\n";
}


0 commentaires