2009-05-25 10 views

Antwort

11

Q1: ja. Sie können jeden Typ übergeben, nicht die notwendigen Typen, die von std :: exception erben.
können Sie schreiben throw 1; zu werfen und int oder throw "hello";, um eine char* zu werfen, die beide nicht erben von std::exception. Dies wird jedoch als schlechte Übung angesehen, da der Benutzer der Klasse nicht erwarten kann, dass Sie etwas werfen. Wenn Sie nicht von std::exception erben möchten, erstellen Sie normalerweise eine eigene Ausnahmehierarchie.

Q2: das Abfangen einer Ausnahme nach Wert (2. Option) ist eine schlechte Methode, da Sie die Ausnahmeinstanz zum Kopieren zwingen und möglicherweise Zuordnungen vornehmen, die weitere Ausnahmen verursachen können.
Die erste Option schlägt vor, dass Sie beabsichtigen, e im catch-Block zu ändern, was Sie wahrscheinlich auch vermeiden möchten, da Ausnahmen normalerweise nach der Erstellung unverändert bleiben. Das einzige, was übrig bleibt, ist die dritte Option.

+0

"Das einzige, was übrig bleibt, ist die dritte Option" - Eine andere Option, aber keine wirklich gute Option, ist das Werfen und Fangen nach Zeiger. – ChrisW

+0

@ChrisW: Auch wenn Microsoft es durch COM zu einer allgemeinen Option gemacht hat, wird das Werfen und Fangen nach Zeiger im Allgemeinen nicht empfohlen. http://www.parashift.com/c++faq-lite/exceptions.html#faq-17.6 –

+3

@ Dribeas - COM macht Ausnahmen eine völlig andere Art; Allerdings hat MS ihre MFC-Bibliothek entworfen, um Zeiger zu werfen/abzufangen. Dies war, weil, als sie zuerst versuchten, es zu implementieren, ihr C++ - Compiler keine Ausnahmen unterstützte! Es waren also nur Makros über setjmp/longjmp, ohne dass sich der Stapel abwickelte ... unglaublich unausgegoren. –

6

Es ist sicher, Sie können jeden beliebigen Typ werfen, und es muss nicht von std::exception abgeleitet werden.

Abfangen einer const Referenz ist besser. Der Grund ist, dass Sie eine const oder eine nicht const werfen können, und es kann von einem nicht const gefangen werden. Das funktioniert wie ein stiller Casting weg von const.

+1

Zum Beispiel "throw 1;" ist legal. – ChrisW

+0

Ich liebe 'werfen "Fnugle nicht gefunden"' für Testcode. – peterchen

+0

Können Sie mir ein Beispiel geben, warum es besser ist, mit const zu fangen? Eine gefährliche Situation, wo Sie stattdessen mit st :: e greifen? –

4

Die Antwort auf Ihre zweite Frage ist, dass Sie nach Wert werfen und durch Bezugnahme fangen sollten. Wenn Sie nach Wert suchen, erhalten Sie 'object slicing'.

+1

Zusätzlich die Unannehmlichkeit, während des Kopierens möglicherweise weitere Ausnahmen auszulösen (Kopie der internen Daten der Ausnahme, Zuweisung der internen Puffer --beachte eine Nachrichtenfolge) –

0

Manchmal ist es notwendig, eine Ausnahme auszulösen, die nicht von std :: exception erbt. Wenn Sie eine gemeinsam genutzte Bibliothek versenden, empfiehlt es sich, die meisten std-Bibliothekstypen entweder neu zu implementieren oder einzubinden, anstatt Methoden/Funktionen, die sie direkt verwenden, offenzulegen, da dies zu Problemen bei der Interoperabilität zwischen Linkern und Compilern führen kann.

Verwandte Themen