Бьерн Страуструп - Язык программирования С++. Главы 8-10 - Реализация списка
ОГЛАВЛЕНИЕ
Страница 7 из 65
8.3.3 Реализация списка
Реализация функций slist_base очевидна. Единственная трудность связана с обработкой ошибок. Например, что делать если пользователь с помощью функции get() пытается взять элемент из пустого списка. Подобные ситуации разбираются в функции обработки ошибок slist_handler(). Более развитый метод, рассчитанный на особые ситуации, будет обсуждаться в главе 9.Приведем полное описание класса slist_base:
class slist_base {Чтобы упростить реализацию обеих функций insert и append, хранится указатель на последний элемент замкнутого списка:
slink* last; // last->next является началом списка
public:
void insert(slink* a); // добавить в начало списка
void append(slink* a); // добавить в конец списка
slink* get(); // удалить и возвратить
// начало списка
void clear() { last = 0; }
slist_base() { last = 0; }
slist_base(slink* a) { last = a->next = a; }
friend class slist_base_iter;
};
void slist_base_insert(slink* a) // добавить в начало спискаЗаметьте, что last->next - первый элемент списка.
{
if (last)
a->next = last->next;
else
last = a;
last->next = a;
}
void slist_base::append(slink* a) // добавить в конец спискаВозможно более гибкое решение, когда slist_handler - указатель на функцию, а не сама функция. Тогда вызов
{
if (last) {
a->next = last->next;
last = last->next = a;
}
else
last = a->next = a;
}
slist* slist_base::get() // удалить и возвратить начало списка
{
if (last == 0)
slist_handler("нельзя взять из пустого списка");
slink* f = last->next;
if (f== last)
last = 0;
else
last->next = f->next;
return f;
}
slist_handler("нельзя взять из пустого списка");будет задаваться так
(*slist_handler)(" нельзя взять из пустого списка");Как мы уже делали для функции new_handler ($$3.2.6), полезно завести функцию, которая поможет пользователю создавать свои обработчики ошибок:
typedef void (*PFV)(const char*);Особые ситуации, которые обсуждаются в главе 9, не только дают альтернативный способ обработки ошибок, но и способ реализации slist_handler.
PFV set_slist_handler(PFV a)
{
PFV old = slist_handler;
slist_handler = a;
return old;
}
PFV slist_handler = &default_slist_handler;