Реализация списка
Реализация функций slist_base очевидна. Единственная трудность связана с обработкой ошибок. Например, что делать если пользователь с помощью функции get() пытается взять элемент из пустого списка. Подобные ситуации разбираются в функции обработки ошибок slist_handler(). Более развитый метод, рассчитанный на особые ситуации, будет обсуждаться в лекции 9.
Приведем полное описание класса slist_base:
class slist_base { 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; };
Чтобы упростить реализацию обеих функций insert и append, хранится указатель на последний элемент замкнутого списка:
void slist_base_insert(slink* a) // добавить в начало списка { if (last) a->next = last->next; else last = a; last->next = a; }
Заметьте, что last->next - первый элемент списка.
void slist_base::append(slink* a) // добавить в конец списка { 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("нельзя взять из пустого списка");
будет задаваться так
(*slist_handler)(" нельзя взять из пустого списка");
Как мы уже делали для функции new_handler (§3.2.6), полезно завести функцию, которая поможет пользователю создавать свои обработчики ошибок:
typedef void (*PFV)(const char*);
PFV set_slist_handler(PFV a) { PFV old = slist_handler; slist_handler = a; return old; }
PFV slist_handler = &default_slist_handler;
Особые ситуации, которые обсуждаются в лекции 9, не только дают альтернативный способ обработки ошибок, но и способ реализации slist_handler.