2008-09-29 5 views

Antwort

29

die zweite. Hier ist mein Versuch, Sutter zitiert

"Werfen von Wert, catch by reference"

lernen catch richtig: Werfen Sie Ausnahmen von Wert (nicht Zeiger) und fangen sie durch Verweis (in der Regel auf const) . Dies ist die Kombination , die am besten mit der Ausnahmesemantik ineinandergreift. Wenn Sie die gleiche Ausnahme erneut auslösen, bevorzugen Sie nur throw; bis throw e;.

Hier ist die volle Item 73. Throw by value, catch by reference.


Der Grund zu vermeiden Ausnahmen von Wert zu kontrollieren ist, dass es implizit eine Kopie der Ausnahme macht. Wenn die Ausnahme einer Unterklasse entspricht, gehen Informationen darüber verloren.

Das Abfangen durch Referenz vermeidet dieses Problem, indem die Ausnahme nicht kopiert wird.

try { throw MyException ("error") } 
catch (Exception& e) { 
    /* Implies: Exception &e = MyException ("error"); */ 
    /* e is an instance of MyException */ 
} 
+0

meinst du das erste? –

+0

Doug T: Nein der zweite. Fang als Referenz. –

+0

Ein bisschen mehr Detail in der Antwort wäre nett. Hinterlassen Sie den Link für die genauen Details, aber geben Sie Details (und Beispiel) über die am meisten akzeptierte Methode an. –

3

Definitiv die zweite. Wenn Sie die folgende hatte:

class my_exception : public exception 
{ 
    int my_exception_data; 
}; 

void foo() 
{ 
    throw my_exception; 
} 

void bar() 
{ 
    try 
    { 
    foo(); 
    } 
    catch (exception e) 
    { 
    // e is "sliced off" - you lose the "my_exception-ness" of the exception object 
    } 
} 
+0

Ich glaube, der Punkt der Frage war, ob durch Referenz oder nach Wert zu fangen, nicht ob eine Basisklasse Version der Ausnahme zu fangen. –

+1

Das Slicing-Problem ist einer der Hauptgründe, die Sie immer durch Bezugnahme fangen sollten –

+0

Ich sehe jetzt, was Sie meinen - wenn e durch Bezugnahme in Ihrem Beispiel gefangen würde, würde Polymorphismus in geeigneter Weise einspringen. –

6

Beachten Sie auch, dass, wenn MFC verwenden, können Sie auf catch by pointer haben. Ansonsten ist @ JaredPars Antwort die Art und Weise, wie Sie normalerweise gehen sollten (und hoffentlich niemals mit Dingen umgehen müssen, die einen Zeiger werfen).

11

Persönlich würde ich für die dritte Option gehen:

catch (const _com_error& e) 
+0

Ja, wenn überhaupt möglich, sollte es const sein. – Miquella