Язык программирования C++ от Страуструпа

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


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



Содержание раздела