2016-12-07 11 views
29

Mam zagnieżdżony kod try-catch jak poniżej:ex.what() zmiany zagnieżdżonego try-catch

void A() 
{ 
    try 
    { 
     //Code like A = string(NULL) that throws an exception 
    } 
    catch(std::exception& ex) 
    { 
     cout<<"in A : " << ex.what(); 
     throw ex; 
    } 
} 

void B() 
{ 
    try 
    { 
     A(); 
    } 
    catch(std::exception& ex) 
    { 
     cout<<"in B : " << ex.what(); 
    } 
} 

Po uruchomieniu tego mam ten wynik:

in A: basic_string::_M_construct null not valid 
in B: std::exception 

jak można zobacz, ex.what() działa OK w funkcji A i powiedz mi poprawny opis, ale w B ex.what() mówi mi tylko std::exception. Dlaczego to się dzieje?

Czy w klauzuli catch funkcji A wystaje coś innego? Jak wyrzucić zagnieżdżony wyjątek, aby uzyskać dokładny opis wyjątku w B?

+1

Patrz: http://stackoverflow.com/questions/1481612/what-is-the-difference-between-throw-and-throw -z-arg-z-złapanego-wyjątku, http://stackoverflow.com/questions/1833982/in-c-is-there-a-difference-between-throw-and-throw-ex –

Odpowiedz

41

Wymień throw ex; na throw;.

Robi to ostatnie będzie ponownie rzucić wyjątek ex, przez odniesienie, więc eliminując zagrożenia przy próbie wykonania kopii wartość: zobacz What is object slicing?

(Zauważ, że wolno modyfikowaćex nawet jeśli napiszesz throw).

+0

z całym szacunkiem dla @ Odpowiedź StoryTeller, akceptuję twoją z powodu dodatkowego łącza i twojego punktu na końcu. –

+3

Nitpick, ale zakładam, że masz na myśli 'throw;', ponieważ (AFAIK) 'throw' na własną rękę nie jest poprawny. –

32

Przerzucasz kopię wyjątku ex w A. Co powoduje, że krojenie obiektów zmienia konkretny wyjątek w std::exception.

Aby ponownie wyświetlić rzeczywisty wyjątek, który został złapany polimorficznie, należy użyć instrukcji throw;.

Warto pamiętać, co Scott Meyers mówi w swojej książce. Rzucacie przez wartość i powinniście złapać przez odniesienie.

+2

Byłeś kilka sekund za mną. Mieć uptoote! – Bathsheba

7

Jesteś slicing oryginalny obiekt wyjątku, spróbuj

try { 
    throw std::runtime_error("Hello world"); 
} 
catch (std::exception& ex) 
{ 
    cout << "in A : " << ex.what(); 
    throw; // Rethrows the original exception - no copy or slicing 
    ^^^^^^ 
} 
Powiązane problemy