Blocuri try-catch imbricate
Unele construcții try-catch pot conține altele. Dacă o excepție apare într-o construcție try-catch imbricată, programul caută mai întâi în această construcție un bloc catch care să gestioneze tipul respectiv de excepție. Dacă în construcția try-catch internă nu este găsit un astfel de bloc catch, atunci programul începe să caute un bloc catch potrivit în construcția try-catch externă. Să vedem un exemplu:
#include <iostream>
double divide(int a, int b)
{
if(!b) // dacă b == 0
{
throw "Division by zero";
}
return a / b;
}
int main()
{
try
{
try
{
int a{10}, b{};
double result {divide(a, b)};
std::cout << result << std::endl;
}
catch (const char* error)
{
std::cout << "Inner exception: " << error << std::endl;
}
std::cout << "Inner try-catch finished" << std::endl;
}
catch (const char* error)
{
std::cout << "External exception: " << error << std::endl;
}
std::cout << "External try-catch finished" << std::endl;
}
Aici, funcția divide() este apelată în construcția try-catch internă. Operatorul throw generează o excepție al cărei obiect este un literal de tip șir de caractere — adică de tip const char*. În blocul try-catch intern există un bloc catch care gestionează excepțiile de tip const char*. După executarea acestuia, programul își continuă execuția normală, iar blocul catch din construcția externă nu se execută. Prin urmare, ieșirea pe consolă va fi:
Inner exception: Division by zero
Inner try-catch finished
External try-catch finished
Acum luăm o altă situație – în construcția try-catch internă nu există blocul catch potrivit:
#include <iostream>
double divide(int a, int b)
{
if(!b) // dacă b == 0
{
throw "Division by zero";
}
return a / b;
}
int main()
{
try
{
try
{
int a{10}, b{};
double result {divide(a, b)};
std::cout << result << std::endl;
}
catch (unsigned error)
{
std::cout << "Inner exception: " << error << std::endl;
}
std::cout << "Inner try-catch finished" << std::endl; // această linie nu este executată
}
catch (const char* error)
{
std::cout << "External exception: " << error << std::endl;
}
std::cout << "External try-catch finished" << std::endl;
}
Practic, este același exemplu, doar că acum blocul catch din interior gestionează excepții de tip unsigned. Astfel, când este generată o excepție, construcția internă nu va găsi blocul catch potrivit pentru excepții de tip const char*. Prin urmare, execuția programului va trece în blocul catch din construcția externă try-catch, care gestionează excepțiile de tip const char*. Ieșirea pe consolă va fi:
External exception: Division by zero
External try-catch finished