attraper des objets d'exception par référence, Temporaires, les questions de vie

StackOverflow https://stackoverflow.com/questions/1860064

  •  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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top