2016-07-12 8 views
7

Ich habe viel für die Unterschiede zwischen diesen beiden Arten von Handlern gesucht, aber jeder sagte, dass catch(...) ein generischer Handler ist, der alles fängt.Gibt es eine Ausnahme, die catch (...) verarbeiten kann, während catch (exception & ex) nicht kann?

Ich konnte keine Ausnahme finden, die eine von ihnen behandeln kann und die andere nicht. Wenn Sie sogar durch Null teilen, wird eine Ausnahme erzeugt, die beide nicht verarbeiten können (Gleitkommaausnahme).

Kann mir jemand eine Probe geben und deutlich ihren Unterschied erklären? Welchen von denen sollte ich verwenden?

+3

'if (i <0)" Oh! My !! ";' – Arunmu

+5

'throw 0;' .... – songyuanyao

+2

Division durch Null löst keine Ausnahme aus. 'werfen 5;' tut, obwohl. – Hurkyl

Antwort

7

Gibt es eine Ausnahme, dass catch(...) umgehen kann, während catch(exception& ex) nicht?

Ja, jede Ausnahme, die von nicht oder nicht std::exception abgeleitet ist, wird nicht von catch(exception&) gefangen werden. Beispielsweise; throw 42; wird von catch(...) abgefangen, aber nicht catch(exception&).

Ein throw exception(); kann entweder gefangen werden; Der erste Handler wird ausgewählt. Der catch(...) sollte der letzte Handler sein.

Auch durch Null teilen, erzeugt eine Ausnahme, die beide nicht (Gleitkommaausnahme) behandeln ...

Visual Studio hat zwei Modi von Ausnahmebehandlung; synchron (/EHsc) und asynchron (/EHa). Für die synchrone Behandlung werden sowohl catch(...) als auch catch(exception&) nur C++ - Ausnahmen abfangen; d.h. diejenigen, die mit einer geworfen werden. Bei der asynchronen Behandlung können Zugriffsverletzungen etc. mit catch(...) abgefangen werden.

VS bietet auch eine Funktion _set_se_translator(), die verwendet werden kann, um die Win32-Ausnahmen zu "übersetzen" oder zu behandeln. In der Regel wird die Funktion zum Konvertieren der Win32-Ausnahme in eine C++ - Ausnahme (abgeleitet von exception) verwendet, die von catch(exception&) verarbeitet werden kann.

Ein Beispiel dafür, wie die Übersetzung aussehen könnte (einige Details werden der Kürze halber weggelassen);

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(); 
} 

Welche von ihnen soll ich verwenden?

Sie sollten den verwenden, mit dem Sie etwas tun können. Wenn alle Ausnahmen zu derselben Behandlung in Ihrem Code führen, verwenden Sie catch(...). Wenn Ihr Code die Ausnahmen getrennt behandeln muss, sollten Sie einen Handler für jede erwartete Ausnahme haben.

5

Sicher, jede Ausnahme, die von einem Typ ist, der nicht std::exception als seine Basisklasse hat nicht von catch(std::exception& ex) gefangen werden.

Zum Beispiel

struct foo {};

throw foo();

wird von catch (...) und nicht durch std::exception gefangen werden.

5

Sie dürfen so ziemlich alles werfen (z. B. int), und catch(...) wird alles fangen. catch(exception&) fängt nur exception oder abgeleitete Typen.

Verwandte Themen