Законченный Класс
Программирование без скрытия данных (с применением структур) требует меньшей продуманности, чем программирование со скрытием данных (с использованием классов). Структуру можно определить не слишком задумываясь о том, как ее предполагается использовать. А когда определяется класс, все внимание сосредотачивается на обеспечении нового типа полным множеством операций; это важное смещение акцента. Время, потраченное на разработку нового типа, обычно многократно окупается при разработке и тестировании программы.
Вот пример законченного типа intset, который реализует понятие "множество целых":
class intset { int cursize, maxsize; int *x; public: intset(int m, int n); // самое большее, m int'ов в 1..n ~intset();
int member(int t); // является ли t элементом? void insert(int t); // добавить "t" в множество
void iterate(int i) { i = 0; } int ok(int i) { return i
void error(char* s) { cerr
Класс intset используется в main(), которая предполагает два целых параметра. Первый параметр задает число случайных чисел, которые нужно сгенерировать. Второй параметр указывает диапазон, в котором должны лежать случайные целые:
main(int argc, char* argv[]) { if (argc != 3) error("ожидается два параметра"); int count = 0; int m = atoi(argv[1]); // число элементов множества int n = atoi(argv[2]); // в диапазоне 1..n intset s(m,n);
while (count maxsize) error("слищком много элементов"); int i = cursize-1; x[i] = t;
while (i0 x[i-1]x[i]) { int t = x[i]; // переставить x[i] и [i-1] x[i] = x[i-1]; x[i-1] = t; i--; } }
Для нахождения членов используется просто двоичный поиск:
int intset::member(int t) // двоичный поиск { int l = 0; int u = cursize-1;
while (l x[m]) l = m+1; else return 1; // найдено } return 0; // не найдено }
И, наконец, нам нужно обеспечить множество операций, чтобы пользователь мог осуществлять цикл по множеству в некотором порядке, поскольку представление intset от пользователя скрыто. Множество внутренней упорядоченности не имеет, поэтому мы не можем просто дать возможность обращаться к вектору (завтра я, наверное, реализую intset по-другому, в виде связанного списка).
Дается три функции: iterate() для инициализации итерации, ok() для проверки, есть ли следующий элемент, и next() для того, чтобы взять следующий элемент:
class intset { // ... void iterate(int i) { i = 0; } int ok(int i) { return iiterate(var); while (set-ok(var)) cout next(var)
Другой способ задать итератор приводится в #6.8.
[] [] []