PDA

Просмотр полной версии : [Информация] Обработка ошибок в с++


TheNevermore
02.04.2012, 17:01
Всем привет,предоставляю немного теории,так как на форуме много людей,что пишут вх,незная азов в языке с++

Обработка ошибок
Создатель библиотеки способен обнаружить динамические ошибки, но не представляет какой в общем
случае должна быть реакция на них. Пользователь библиотеки способен написать реакцию на такие
ошибки, но не в силах их обнаружить. Если бы он мог, то сам разобрался бы с ошибками в своей
программе, и их не пришлось бы выявлять в библиотечных функциях. Для решения этой проблемы в
язык введено понятие особой ситуации.
Только недавно комитетом по стандартизации С++ особые ситуации были включены в стандарт языка,
но на время написания этой книги они еще не вошли в большинство реализаций.
Суть этого понятия в том, что функция, которая обнаружила ошибку и не может справиться с нею,
запускает особую ситуацию, рассчитывая, что устранить проблему можно в той функции, которая прямо
или опосредованно вызывала первую. Если функция рассчитана на обработку ошибок некоторого вида,
она может указать это явно, как готовность перехватить данную особую ситуацию.
Рассмотрим в качестве примера как для класса Vector можно представлять и обрабатывать особые
ситуации, вызванные выходом за границу массива:
class Vector {
int* p;
int sz;
public:
class Range { }; // класс для особой ситуации
int& operator[](int i);
// ...
};
Предполагается, что объекты класса Range будут использоваться как особые ситуации, и запускать их
можно так:
int& Vector::operator[](int i)
{
if (0<=i && i<sz) return p[i];
throw Range();
}
Если в функции предусмотрена реакция на ошибку недопустимого значения индекса, то ту часть
функции, в которой эти ошибки будут перехватываться, надо поместить в оператор try. В нем должен
быть и обработчик особой ситуации:
void f(Vector& v)
{
// ...
try {
do_something(v); // содержательная часть, работающая с v
}
catch (Vector::Range) {

// обработчик особой ситуации Vector::Range
// если do_something() завершится неудачно,
// нужно как-то среагировать на это
// сюда мы попадем только в том случае, когда
// вызов do_something() приведет к вызову Vector::operator[]()
// из-за недопустимого значения индекса
}
// ...
}
Обработчиком особой ситуации называется конструкция
catch ( /* ... */ ) {
// ...
}
Ее можно использовать только сразу после блока, начинающегося служебным словом try, или сразу
после другого обработчика особой ситуации. Служебным является и слово catch. После него идет в
скобках описание, которое используется аналогично описанию формальных параметров функции, а
именно, в нем задается тип объектов, на которые рассчитан обработчик, и, возможно, имена
параметров (см. $$9.3). Если в do_something() или в любой вызванной из нее функции произойдет
ошибка индекса (на любом объекте Vector), то обработчик перехватит особую ситуацию и будет
выполняться часть, обрабатывающая ошибку. Например, определения следующих функций приведут к
запуску обработчика в f():
void do_something()
{
// ...
crash(v);
// ...
}

void crash(Vector& v)
{
v[v.size()+10]; // искусственно вызываем ошибку индекса
}
Процесс запуска и перехвата особой ситуации предполагает просмотр цепочки вызовов от точки
запуска особой ситуации до функции, в которой она перехватывается. При этом восстанавливается
состояние стека, соответствующее функции, перехватившей ошибку, и при проходе по всей цепочке
вызовов для локальных объектов функций из этой цепочки вызываются деструкторы. Подробно это
описано в $$9.4.
Если при просмотре всей цепочки вызовов, начиная с запустившей особую ситуацию функции, не
обнаружится подходящий обработчик, то программа завершается. Подробно это описано в $$9.7.
Если обработчик перехватил особую ситуацию, то она будет обрабатываться и другие, рассчитанные на
эту ситуацию, обработчики не будут рассматриваться. Иными словами, активирован будет только тот
обработчик, который находится в самой последней вызывавшейся функции, содержащей
соответствующие обработчики. В нашем примере функция f() перехватит Vector::Range, поэтому эту
особую ситуацию нельзя перехватить ни в какой вызывающей f() функции:
int ff(Vector& v)
{
try {
f(v); // в f() будет перехвачена Vector::Range
}
catch (Vector::Range) { // значит сюда мы никогда не попадем
// ...
}
}[/COLOR][/SIZE][/FONT] :flood:

warl0ck
02.04.2012, 17:29
сделай текст читаемым + отключи смайлы в тексте

Евгеша390
02.04.2012, 18:30
Спасибо, пригодится)

Falkor 007
02.04.2012, 19:24
Думаю не помешает выделить текст от кода цветами, в этом правда не разбираюсь, но в цветах будет понятнее, уверен в этом потому что html когда изучал, в цветах было удобнее)))

DefenderYO
02.04.2012, 19:30
Евгеша390, ты хоть прочитал?/horror