8.3.3 Реализация списка.

   


Назад  |  Вперёд

Реализация функций 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.


Назад  |  Вперёд


OtDiatlovaOU
К началу книги

Оформление и дизайн книги OtDiatlovaOU.
Вся книга, архив.