Листинг 7.9. Методы удаления из дека с генерацией исключений
void TDeque::pop_front() { if (MsEmptyO) { Elem *p = Head:
Head = Head->next:
Head->prev = 9:
head = iterator(Head);
--count; delete р;
else throw emptyDequeO ;
// генерация исключения
}
void TDeque: :pop_back'() { if (MsEmptyO)
{ Elem *p = Tail->prev; if (p == 0) pop_front(); else
{ p->prev->next = Tail; Tail->prev = p->prev; delete p;
}
--count;
else throw emptyDequeO;
// генерация исключения
Операция разыменования итератора operator *, очевидно, должна генерировать другое исключение — назовем его invalidlterator. Текст операции с генерацией исключения представлен в листинге 7.10.
Листинг 7.10. Операция разыменования с генерацией исключения
value_type& operator*() const { if (the_elem != 0) return the_elem->item; else throw invalidlterator();
}
Нужно еще обратить внимание на то, что операция new может генерировать стандартное исключение1 bad_alloc (см. п. п. 18.4.2.1 в [1]), если запрос на память не может быть удовлетворен. Таким образом, программа-клиент, использующая наши динамические контейнеры, обязана перехватывать и обрабатывать не только объявленные нами исключения, но и исключение bad_alloc.
Отметим, что операция new выполняется в конструкторе, однако утечки памяти не происходит, так как память не была выделена, — вместо этого генерируется исключение. И в этом случае выполняется обычная раскрутка стека, то есть для всех локальных объектов, определенных в конструкторе, вызываются деструкторы и объекты уничтожаются. Затем начинается поиск подходящей секции-ловушки. |