2010-09-23 11 views
5

Mamy zabawny problem z wypróbowaniem catch i std :: runtime_error. Czy ktoś może mi wyjaśnić, dlaczego powraca "Nieznany błąd" jako wynik? Dziękuję bardzo za pomoc!Błąd z przechwytywaniem std :: runtime_error jako std :: wyjątek

#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

Drukuje "FunnyError" Dla mnie, przy użyciu Visual C++ 2010. Które kompilatora używasz? – Doug

+0

Visual Studio 2005 – BlueTrin

Odpowiedz

17

Problem dotyczy tej linii. Ponieważ throw z wyrażeniem używa typu statycznego tego wyrażenia w celu określenia zgłaszanego wyjątku, powoduje to przekrojenie obiektu wyjątku, który tworzy nowy obiekt obiektu bazowego std::exception, który jest odniesieniem do obiektu bazowego.

throw e; 

Aby ponownie rzucić złowionych wyjątek należy zawsze używać rzut bez wyrazu.

throw; 
+2

18 sekund szybciej ... jak on to robi?! –

+1

Ah, konstruktor kopiowania 'exception' nie musi zachowywać' what() '. Nie zdawałem sobie z tego sprawy. – Doug

+0

Charles, myślałem, że rzut e; wywoła konstruktor copy std :: exception (const std :: exception e), który utworzy poprawną kopię wyjątku? Czy tak nie jest? – BlueTrin

0

znalazłem idealną odpowiedzią na ten problem:

C++ czyni wyraźne rozróżnienie między odniesienia i wartość kopii. Użyj

catch (const std::exception& e) 

złapać przez odniesienie zamiast wartości.

Go dać upvotes do oryginalnego odpowiadającego here

+0

Nie przechwyciłem przez kopiowanie wartości. – BlueTrin

Powiązane problemy