2010-09-23 13 views
5

Nous avons un problème amusant avec try catch et std :: runtime_error. Quelqu'un peut-il m'expliquer pourquoi cela renvoie "Erreur inconnue" en sortie? Merci beaucoup de m'avoir aidé!Erreur lors de la capture de std :: runtime_error en tant que std :: exception

#include "stdafx.h" 
#include <iostream> 
#include <stdexcept> 

int magicCode() 
{ 
    throw std::runtime_error("FunnyError"); 
} 

int funnyCatch() 
{ 
    try{ 
     magicCode(); 
    } catch (std::exception& e) { 
     throw e; 
    } 

} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    try 
    { 
     funnyCatch(); 
    } 
    catch (std::exception& e) 
    { 
     std::cout << e.what(); 
    } 
return 0; 
} 
+0

Il imprime "FunnyError" pour moi, en utilisant Visual C++ 2010. Quel compilateur utilisez-vous? – Doug

+0

Visual Studio 2005 – BlueTrin

Répondre

17

Le problème est avec cette ligne. Parce que throw avec une expression utilise le type statique de cette expression pour déterminer l'exception levée, cela découpe l'objet d'exception en construisant un nouvel objet std::exception en ne copiant que la partie d'objet de base du std::runtime_error que e est une référence à. Pour relancer l'exception interceptée, vous devez toujours utiliser throw sans expression.

throw; 
+2

18 secondes plus vite ... comment le fait-il?! –

+1

Ah, le constructeur de copie 'exception' ne doit pas conserver' what() '. Je n'ai pas réalisé ça. – Doug

+0

Charles, je pensais que lancer e; appellerait le constructeur de copie std :: exception (const std :: exception e), ce qui créerait une copie correcte de l'exception? N'est-ce pas le cas? – BlueTrin

0

J'ai trouvé une réponse parfaite à ce problème:

C++ fait une distinction explicite entre copie référence et la valeur. Utilisez

catch (const std::exception& e) 

attraper par référence au lieu de la valeur.

Go pour donner upvotes le répondeur d'origine here

+0

Je n'ai pas capturé par copie de valeur. – BlueTrin