LINUX.ORG.RU

История изменений

Исправление Kroz, (текущая версия) :

Одна из самых классных и при этом самых опасных фич С++ - исключения.

Если какая-то функция хочет завершится ошибкой, но не нужно делать специальный код возврата; достаточно бросить исключение. Особенно это актуально если функция возвращает значение одного типа (в данном случае int), а вместе с ошибкой она хочет передать данные другого типа (в данном случае string).

Чтобы предыдущей функции также завершиться аварийно в случае, если вызванная ею функция завершилась аварийно, там не нужно делать ничего (!). Выход из нее будет сделан автоматически, если только не поставить там блок try-catch. И при этом корректно будут вызваны все конструкторы локальных объектов, а значит и проблем с не-освобожденной памятью (да и другими «завершающими» операциями) нет.

Вобщем, если попробовать сделать аналогичный код на C, то разница будет налицо.

#include<iostream>
#include<string>

using namespace std;

int fn1()
{
        // throw string("Exception in fn1");
        return 1;
}
int fn2()
{
        throw string("Exception in fn2");
        return 2;
}
int fn3()
{
        // throw string("Exception in fn3");
        return 4;
}

int fn()
{
        return fn1() + fn2() + fn3();
}

int main()
{
        string e;

        try {
                cout << "The resut is " << fn() << endl;
        } catch (string &s){
                cout << "Error: " << s << endl;
        }

        return 0;
}
$ g++ ./cpp_exception.cpp && ./a.out
Error: Exception in fn2

Исходная версия Kroz, :

Case 4: Исключения

Одна из самых классных и при этом самых опасных фич С++ - исключения.

Если какая-то функция хочет завершится ошибкой, но не нужно делать специальный код возврата; достаточно бросить исключение. Особенно это актуально если функция возвращает значение одного типа (в данном случае int), а вместе с ошибкой она хочет передать данные другого типа (в данном случае string).

Чтобы предыдущей функции также завершиться аварийно в случае, если вызванная ею функция завершилась аварийно, там не нужно делать ничего (!). Выход из нее будет сделан автоматически, если только не поставить там блок try-catch. И при этом корректно будут вызваны все конструкторы локальных объектов, а значит и проблем с не-освобожденной памятью (да и другими «завершающими» операциями) нет.

Вобщем, если попробовать сделать аналогичный код на C, то разница будет налицо.

#include<iostream>
#include<string>

using namespace std;

int fn1()
{
        // throw string("Exception in fn1");
        return 1;
}
int fn2()
{
        throw string("Exception in fn2");
        return 2;
}
int fn3()
{
        // throw string("Exception in fn3");
        return 4;
}

int fn()
{
        return fn1() + fn2() + fn3();
}

int main()
{
        string e;

        try {
                cout << "The resut is " << fn() << endl;
        } catch (string &s){
                cout << "Error: " << s << endl;
        }

        return 0;
}