2009-02-16 11 views
13

Kann ich try-catch-Blöcke verschachtelt haben? Zum Beispiel:Kann ich try-catch-Blöcke in C++ verschachtelt haben?


void f() 
{ 
    try 
    { 
     //Some code 
     try 
     { 
      //Some code 
     } 
     catch(ExceptionA a) 
     { 
      //Some specific exception handling 
     } 
     //Some code 
    } 
    catch(...) 
    { 
     //Some exception handling 
    } 
}//f 
+3

Sie müssen diese Leute lieben, die denken, dass sie schlauer sind als alle anderen und denken, dass sie diese Webseite besitzen. –

+2

Ich gebe diesen Fragen im Allgemeinen den Vorteil des Zweifels: nur weil es auf Ihrem Compiler funktioniert, bedeutet es nicht, dass es Teil ist des Standards. Das Gegenteil ist auch richtig. – rmeador

+2

@shoosh diese Frage rettete mich mindestens 90 Sekunden vom Nachschlagen! –

Antwort

19

Ja vollkommen legal.

Obwohl es am besten wäre, inner diejenigen in einer anderen Methode zu bewegen, um es sauberer aussieht und Ihre Methode (n) kleiner ist

1

Ja, Sie können.

7

Wie bereits erwähnte, ist es möglich, aber Sie müssen sehen, die ‚Durchsturz "-Schema in diesem. Wenn Ihre Ausnahme im ersten try-catch-Block gefangen wird, wird sie nicht vom äußeren catch-block erfasst. Wenn es jedoch nicht vom inneren catch-block erfasst wird, wird es versuchen, einen passenden Ausnahme-Handler im äußeren catch-block zu finden.

Sie können die Ausnahme auch explizit zum nächsten Ausnahmehandler auslösen, indem Sie in Ihrem inneren Ausnahmebehandler throw; verwenden.

Zum Beispiel dieser Code:

try 
{ 
    try 
    { 
     throw std::runtime_error("Test"); 
    } 
    catch (std::runtime_error& e) 
    { 
     std::cerr << "Inner Exception-Handler: " << e.what() << std::endl; 
     throw; 
    } 
} 
catch (std::exception& e) 
{ 
    std::cerr << "Outer Exception-Handler: " << e.what() << std::endl; 
}

Wird in Folge:

Inner Exception-Handler: Test 
Outer Exception-Handler: Test

Das funktioniert, weil std::runtime_error is derived from std::exception. Sie sollten auch beachten, dass es in solch einem trivialen Beispiel auch möglich ist, die catch-Blöcke einfach hintereinander zu schreiben, aber wenn Sie anderen Code nach dem ersten catch-Block ausführen möchten, müssen Sie sie verschachteln.

1

Es ist legal, aber es ist nicht so nützlich, es sei denn, Sie werfen eine Ausnahme von Ihrem inneren catch(). Beispielsweise möchten Sie möglicherweise eine Ausnahme auf Systemebene abfangen, aber Ihr eigenes Ausnahmeobjekt für die Klarheit des Codes werfen.

+3

Es ist nützlich, wenn der äußere Catch eine andere Reihe von Ausnahmen behandelt – MSalters

5

Ja, das ist legal. Wie ouster sagte, ist eine Möglichkeit, damit umzugehen, den inneren try-catch-Block in seine eigene Funktion zu setzen und diese Funktion von Ihrem äußeren try-catch-Block aus aufzurufen.

Eine andere Möglichkeit, damit umzugehen, ist mit mehreren Catch-Blöcken.

void f() 
{ 
    try 
    { 
     //Some code that throws ExceptionA 
     //Some code that throws ExceptionB 
    } 
    catch(ExceptionA ea) 
    { 
     //Some exception handling 
    } 
    catch(ExceptionB eb) 
    { 
     //Some exception handling 
    } 
}//f 

Die Sache, die hier zu beachten ist, ist die Spezifität der Ausnahmetypen in Ihren Catch-Blöcken. Wenn ExceptionB ExceptionA im obigen Beispiel erweitert, wird der Block "ExceptionB" niemals aufgerufen, da jede ExceptionB, die ausgelöst wird, vom ExceptionA-Block behandelt wird. Bei Ausnahmeklassenhierarchien müssen Sie die Catch-Blöcke in der am wenigsten spezifischen Reihenfolge sortieren.

Verwandte Themen