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?
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:
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).
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
:
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.
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:)
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.
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.
Tags und Links c++ exception-handling