2009-02-16 11 views
13

Posso avere blocchi di try-catch nidificati? Ad esempio:Posso avere blocchi di try-catch nidificati in C++?


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

Devi solo amare queste persone che pensano di essere più intelligenti di chiunque altro e pensano di possedere questo sito web –

+2

Solitamente questo tipo di domande mi dà il beneficio del dubbio: solo perché funziona sul tuo compilatore non significa che sia parte dello standard. Il contrario è anche vero. – rmeador

+2

@shoosh questa domanda mi ha salvato almeno 90 secondi dalla ricerca! –

risposta

19

Sì perfettamente legale.

Anche se sarebbe meglio spostare gli interni in un altro metodo in modo che appaia più pulito e il metodo di (s) sono più piccoli

1

Sì, è possibile.

7

Come già detto, è possibile, ma bisogna vedere il 'cadere-through '-schema in questo. Se nel primo try-catch-block viene rilevata l'eccezione, questa non verrà catturata dal blocco catch esterno. Tuttavia, se non viene catturato dal blocco catch interno, cercherà di trovare un gestore di eccezioni corrispondente nel catch-block esterno.

È anche possibile aumentare in modo esplicito l'eccezione al successivo gestore di eccezioni utilizzando throw; nel gestore di eccezioni interno.

Per esempio questo codice:

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; 
}

si tradurrà in:

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

Questo funziona perché std::runtime_error is derived from std::exception. Dovresti anche notare che in un esempio così banale è anche possibile scrivere i blocchi di cattura l'uno dopo l'altro, ma se vuoi eseguire altro codice dopo il primo catch-block dovrai nidificarli.

1

È legale ma non è così utile a meno che non si stia emettendo un'eccezione dalla propria presa interiore(). Ad esempio, potresti voler rilevare un'eccezione a livello di sistema ma lanciare il tuo oggetto di eccezione per la chiarezza del codice.

+3

È utile se il fermo esterno gestisce un diverso insieme di eccezioni – MSalters

5

Sì, è legale. Come diceva ouster, un modo per affrontarlo è mettere il blocco try-catch interno nella propria funzione e chiamare quella funzione dal blocco try-catch esterno.

Un altro modo per gestirlo è con più blocchi catch.

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 

La cosa da fare attenzione qui è la specificità dei tipi di eccezioni nei blocchi di cattura. Se ExceptionB estende ExceptionA nell'esempio precedente, il blocco ExceptionB non verrebbe mai chiamato perché qualsiasi ExceptionB che viene generata verrà gestita dal blocco ExceptionA. È necessario ordinare i blocchi catch nell'ordine più specifico o meno specifico quando si gestiscono le gerarchie di classi Exception.