Как Этим Пользоваться
Фактически класс slist в написанном виде бесполезен. В конечном счете, зачем можно использовать список указателей void*? Штука в том, чтобы вывести класс из slist и получить список тех объектов, которые представляют интерес в конкретной программе. Представим компилятор языка вроде C++. В нем широко будут использоваться списки имен; имя - это нечто вроде
struct name { char* string; // ... };
В список будут помещаться указатели на имена, а не сами объекты имена. Это позволяет использовать небольшое информационное поле e slist'а, и дает возможность имени находиться одновременно более чем в одном списке. Вот определение класса nlist, который очень просто выводится из класса slist:
#include "slist.h" #include "name.h"
struct nlist : slist { void insert(name* a) { slist::insert(a); } void append(name* a) { slist::append(a); } name* get() {} nlist(name* a) : (a) {} };
Функции нового класса или наследуются от slist непосредственно, или ничего не делают кроме преобразования типа. Класс nlist - это ничто иное, как альтернативный интерфейс класса slist. Так как на самом деле тип ent есть void*, нет необходимости явно преобразовывать указатели name*, которые используются в качестве фактических параметров (#2.3.4).
Списки имен можно использовать в классе, который представляет определение класса:
struct classdef { nlist friends; nlist constructors; nlist destructors; nlist members; nlist operators; nlist virtuals; // ... void add_name(name*); classdef(); ~classdef(); };
и имена могут добавляться к этим спискам приблизительно так:
void classdef::add_name(name* n) { if (n-is_friend()) { if (find(friends,n)) error("friend redeclared"); else if (find(members,n)) error("friend redeclared as member"); else friends.append(n); } if (n-is_operator()) operators.append(n); // ... }
где is_iterator() и is_friend() являются функциями членами класса name. Фукнцию find() можно написать так:
int find(nlist* ll, name* n) { slist_iterator ff(*(slist*)ll); ent p; while ( p=ff() ) if (p==n) return 1; return 0; }
Здесь применяется явное преобразование типа, чтобы применить slist_iterator к nlist. Более хорошее решение, - сделать итератор для nlist'ов, приведено в #7.3.5. Печатать nlist может, например, такая функция:
void print_list(nlist* ll, char* list_name) { slist_iterator count(*(slist*)ll); name* p; int n = 0; while ( count() ) n++; cout string