История изменений
Исправление 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;
}