2016-07-12 15 views
7

Często szukałem różnic między tymi dwoma typami programów obsługi, ale wszyscy mówili, że catch(...) to ogólny program obsługi, który przechwytuje wszystko.Czy istnieje wyjątek, który można przechwycić (...) podczas wstrzymania (wyjątek i ex) nie może?

Nie mogłem znaleźć żadnego wyjątku, który mógłby obsłużyć jeden z nich, a drugi nie. Nawet dzielenie przez zero tworzy wyjątek, z którym obaj nie mogą sobie poradzić (wyjątek zmiennoprzecinkowy).

Czy ktoś może dać mi próbkę i wyjaśnić wyraźnie ich różnicę? Którego z nich powinienem użyć?

+3

'jeśli (i <0) rzuciło" Oh! My !! ";' – Arunmu

+5

'throw 0;' .... – songyuanyao

+2

Podziel przez zero nie wyrzuca wyjątku. 'throw 5;' robi, chociaż. – Hurkyl

Odpowiedz

7

Czy istnieje wyjątek, który może obsługiwać jednocześnie catch(...)catch(exception& ex) nie może?

Tak, każdy wyjątek, który nie jest lub nie pochodzi z std::exception, nie zostanie przechwycony przez catch(exception&). Na przykład; throw 42; zostanie przechwycony przez catch(...), ale nie pod numerem catch(exception&).

A throw exception(); może zostać przechwycony przez; wybierany jest pierwszy program obsługi. catch(...) powinien być ostatnim programem obsługi.

Nawet dzielić przez zero, tworzy wyjątek, który oboje nie może obsłużyć (floating point wyjątek) ...

Visual Studio posiada dwa tryby obsługi wyjątków; synchroniczny (/EHsc) i asynchroniczny (/EHa). W przypadku obsługi synchronicznej, zarówno catch(...) jak i catch(exception&) będą wychwytywać tylko wyjątki C++; to jest te rzucane z throw xyz;. W przypadku asynchronicznej obsługi, naruszenia dostępu itp. Mogą zostać przechwycone przez catch(...).

VS oferuje również funkcję _set_se_translator(), która może być używana do "tłumaczenia" lub obsługi wyjątków Win32. Zwykle funkcja ta służy do tłumaczenia wyjątku Win32 na wyjątek C++ (pochodzący z exception), który może być obsługiwany przez catch(exception&).

Próbka tego, jak tłumaczenie mogłoby wyglądać (niektóre szczegóły zostały pominięte dla zwięzłości);

struct seh_exception : std::runtime_error { 
    //... 
}; 

struct access_violation : seh_exception { 
    //... 
}; 

struct unspecified_seh_exception : seh_exception { 
    //... 
}; 

void translation_function(unsigned int code, ::EXCEPTION_POINTERS* info) 
{ 
    switch (code) { 
    case EXCEPTION_ACCESS_VIOLATION: 
     throw access_violation(); 
     break; 
    // more cases for other exception codes 
    }; 

    throw unspecified_seh_exception(); 
} 

Który z nich wybrać?

Powinieneś użyć tego, z którym możesz coś zrobić. Jeśli wszystkie wyjątki spowodują takie samo postępowanie z Twoim kodem, użyj catch(...). Jeśli twój kod musi obsługiwać wyjątki osobno, powinieneś mieć procedurę obsługi dla każdego oczekiwanego wyjątku.

5

Oczywiście, każdy wyjątek, który nie ma klasy std::exception jako klasy podstawowej, nie zostanie przechwycony przez catch(std::exception& ex).

Na przykład

struct foo {};

throw foo();

zostanie złapany przez catch (...), a nie przez std::exception.

5

Możesz rzucać prawie wszystko (np. int), a catch(...) złapie wszystko. catch(exception&) będzie tylko przechwytywać exception lub typy pochodne.

Powiązane problemy