attraper des objets d'exception par référence, Temporaires, les questions de vie
-
13-09-2019 - |
Question
Considérez le code suivant:
#include <iostream>
#include <stdexcept>
void foo()
{
throw std::runtime_error("How long do I live?");
}
int main()
{
try
{
foo();
}
catch (std::runtime_error& e)
{
std::cout << e.what() << std::endl;
}
}
Pourquoi puis-je attraper l'exception par référence, n'est pas std::runtime_error("How long do I live?")
rvalue?
Comment se fait l'objet d'exception est toujours en vie dans le bloc catch?
Où exactement sont jetés des objets d'exception stockés? Quelle est leur durée de vie?
Pas de solution correcte
Autres conseils
Dans la norme C du paragraphe 15.1.4:
La mémoire de la copie temporaire de l'exception levée est alloué d'une manière quelconque, sauf indication contraire dans 3.7.3.1. temporaire persiste aussi longtemps que il y a un gestionnaire en cours d'exécution pour que exception . En particulier, si un gestionnaire sort par l'exécution d'une touche; déclaration, qui passe le contrôle un autre gestionnaire pour le même exception, de sorte que les restes temporaires. Lorsque le dernier gestionnaire en cours d'exécution pour les sorties d'exception par tout moyen autre que jeter; l'objet temporaire est détruite et la mise en œuvre peut désallouer la mémoire pour le objet temporaire; une telle désallocation se fait dans un non précisé façon. La destruction se produit immédiatement après la destruction de l'objet déclaré dans la exception déclaration dans le gestionnaire.
Notez que, dans C ++ -. Conversation standard, un gestionnaire désignent un bloc de catch
avec le type d'argument correct
Une exception levée est pas temporaire - le code, l'exception généré par le compilateur conserve une copie permanente de celui-ci. Ainsi, vous pouvez la lier à une référence non-const.
[modifier] Je vérifie juste la norme et il désigne en fait une copie temporaire. Cependant, la durée de vie du temporaire est garanti d'être au moins aussi longue que celle du gestionnaire d'exception.
Comme Neil a dit, il y a la magie du compilateur interne en cours. De plus, sachez que le compilateur est autorisé à créer un certain nombre de copies de l'objet d'exception.
Coup de coeur pour essayer de comprendre les détails de la langue. En même temps, à mon humble avis, il est beaucoup plus important de comprendre pourquoi vous devrait attraper une exception par référence (et le jeter en valeur), que la raison pour laquelle vous peut .
Les gens utilisent généralement une hiérarchie de classes d'exception, et la capture par référence vous permet de tirer parti de polymorphisme, et attrapez une exception de la classe de base, lorsqu'il n'y a pas besoin de manipuler différents types d'exception séparément. Si vous ne pouviez pas prendre en référence, vous auriez dû écrire une clause de catch
pour chaque type d'exception possible qui peut être jeté dans la clause try
.