Введение в язык Си++

Реализация


Реализующие slist функции в основном просты. Единственная настоящая сложность - что делать в случае ошибки, если, например, пользователь попытается get() что-нибудь из пустого списка. Мы обсудим это в Здесь приводятся определения членов slist. Обратите внимание, как хранение указателя на последний элемент кругового списка дает возможность просто реализовать оба действия append() и insert():

int slist::insert(ent a) { if (last) last-next = new slink(a,last-next); else { last = new slink(a,0); last-next = last; } return 0; }

int slist::append(ent a) { if (last) last = last-next = new slink(a,last-next); else { last = new slink(a,0); last-next = last; } return 0; }

ent slist::get() { if (last == 0) slist_handler("get fromempty list"); // взять из пустого списка slink* f = last-next; ent r f-e; if (f == last) last = 0; else last-next = f-next; delete f; return f; }

Обратите внимание, как вызывается slist_handler (его описание можно найти в ). Этот указатель на имя функции используется точно так же, как если бы он был именем функции. Это является краткой формой более явной записи вызова:

(*slist_handler)("get fromempty list");

И slist::clear(), наконец, удаляет из списка все элементы:

void slist::clear() { slink* l = last; if (l == 0) return; do { slink* ll = l; l = l-next; delete ll; } while (l!=last); }

Класс slist не обеспечивает способа заглянуть в список, но только средства для вставления и удаления элементов. Однако оба класса, и slist, и slink, описывают класс slist_iterator как друга, поэтому мы можем описать подходящий итератор. Вот один, написанный в духе :

class slist_iterator { slink* ce; slist* cs; public: slist_iterator(slist s) { cs = s ce = cs-last; }

ent operator()() { // для индикации конца итерации возвращает 0 // для всех типов не идеален, хорош для указателей ent ret = ce ? (ce=ce-next)-e : 0; if (ce == cs-last) ce= 0; return ret; } };



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