MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

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