warum try ... catch erfordert EXACT Typ geworfen

8

Ich kann das tun, kein Problem:

%Vor%

aber wenn ich das versuche:

%Vor%

Ich bekomme eine unbehandelte Ausnahme.

Dies scheint inkonsistent zu sein. Was ist der Grund für keine Konvertierung in diesem Fall?

    
Angus Comber 27.09.2011, 14:09
quelle

5 Antworten

7

Im ersten Fall kann der Compiler genau sagen, was Sie tun möchten: Konvertieren Sie ein long in ein int . Im zweiten Fall muss der Compiler davon ausgehen, dass Sie ein Konstrukt wie dieses haben könnten:

%Vor%

Die Idee ist, dass der Compiler niemals wissen kann, ob sich ein catch (long l) außerhalb des aktuellen Kontexts lauern lässt, also ist es nie sicher, die erste mögliche Konvertierung auszuwählen.

Dies ist auch der Grund, warum es üblich ist, eine Klassenhierarchie zu verwenden, wenn Exceptions anstelle von zufälligen Typen wie int oder long geworfen werden: es macht es einfach, Ihren Exception-Handlern mehr oder weniger Spezifikation hinzuzufügen Der Compiler kann sich Ihrer Absichten sicher sein (über die is-a Beziehung).

    
ladenedge 27.09.2011, 14:21
quelle
4

catch tut nicht benötigt unbedingt den genauen Typ.

Es ist üblich und empfehlenswert, Ausnahmen zu verwenden, die von std::exception (gefunden in <stdexcept> ) abgeleitet sind. Der Grund ist, dass Sie dann polymorph werden können, dh Sie müssen nicht den genauen Typ kennen (siehe auch Unterschied: std :: runtime_error vs std :: exception () ) und wir haben eine Konvention, um dies zu behandeln.

Entweder verwenden Sie eine der vom Standard bereitgestellten Optionen (z. B. std::range_error ) oder, falls nichts für Ihre Probleme [genug] ist, spezialisieren Sie std::exception :

%Vor%

Ausgabe:

%Vor%

Die Konvention besteht darin, durch Referenz oder const-Referenz zu fangen, so dass Sie polymorphes Verhalten erhalten, ohne Objekt-Slicing zu befürchten.

    
Sebastian Mach 27.09.2011 14:36
quelle
1

Die catch-Anweisung fängt ein Objekt (oder eine skalare Variable in Ihren Fällen) aufgrund ihres Typs ab. Wenn der Typ nicht übereinstimmt, wird sie an die nächste catch-Anweisung (falls vorhanden) oder an den Standardausnahmeempfänger übergeben. p>

In Ihrem Fall könnte es sein, dass Sie eine zweite Fanganweisung lange und möglicherweise anderswo abfangen, so dass Ihre Fanganweisung nichts fängt.

Um irgendeine Ausnahme zu fangen, benutzen Sie einfach catch () {}:)

Ein einzelner Tipp, besser Ausnahmeklasse oder Unterklasse für eigene Bedürfnisse:)

    
Geoffroy 27.09.2011 14:17
quelle
1

Sie können auch throw 3; - kein Problem.

int und long sind unterschiedliche Typen. Es ist ein Vorteil der Ausnahmebehandlung, dass Sie die Ausnahmen erkennen können, abgesehen von ihrem Typ (ein zentraler try-Block kann Ausnahmen verschiedener Art von verschiedenen Orten aus behandeln / ein try-Block kann nur einige Arten von Ausnahmen behandeln und andere propagieren).

Es wird auch empfohlen, eine der Standardausnahmen zu werfen oder eine Klasse von einer davon abzuleiten. Dann könnten Sie einfach catch (const std::exception&) verwenden, wenn Sie nur die Ausnahme behandeln möchten und sich nicht um den bestimmten Typ kümmern.

    
UncleBens 27.09.2011 14:22
quelle
0

Sie können mehrere Typen in einem try-catch-Block abfangen. Damit der Compiler erkennt, welcher catch-Block geworfen werden soll, muss er in der Lage sein, den exakten Typ zu ermitteln. Oder es kann einen Standard-Catch-Block haben - catch (...) {} , aber Sie werden nicht in der Lage sein, den Wert zu bekommen, der in diesem Fall geworfen wird.

    
Mark Jones 27.09.2011 14:16
quelle

Tags und Links