Чтение онлайн

на главную

Жанры

Шрифт:

class table (* name** tbl; int size; public: table(int sz = 15); ~table;

name* look(char*, int = 0); name* insert(char* s) (* return look(s,1); *) *);

В структуру данных и конструктор внесены изменения, оражающие необходимость того, что при использовании хэшировния таблица должна иметь определенный размер. Задание конструктора с параметром по умолчанию обеспечивает, что страя программа, в которой не указывался размер таблицы, остнется правильной. Параметры по умолчанию очень полезны в стуации, когда нужно изменить класс не повлияв на старые программы. Теперь конструктор и деструктор создают и уничтжают

хэш-таблицы:

table::table(int sz) (* if (sz « 0) error(„отрицательный размер таблицы“); tbl = new name*[size=sz];

for (int i = 0; i«sz; i++) tbl[i] = 0; *)

table::~table (* for (int i = 0; i«size; i++) for (name* n = tbl[i]; n; n=n-»next) (* delete n-»string; delete n; *) delete tbl; *)

Описав деструктор для класса name можно получить более простой и ясный вариант table::~table. Функция просмотра практически идентична той, которая использовалась в примере настольного калькулятора (#3.1.3):

#include «string.h»

name* table::look(char* p, int ins) (* int ii = 0; char* pp = p; while (*pp) ii = ii««1 ^ *pp++; if (ii « 0) ii = -ii; ii %= size;

for (name* n=tbl[ii]; n; n=n-»next) if (strcmp(p,n-»string) == 0) return n;

if (ins == 0) error(«имя не найдено»);

name* nn = new name; nn-»string = new char[strlen(p)+1]; strcpy(nn-»string,p); nn-»value = 1; nn-»next = tbl[ii]; tbl[ii] = nn; return nn;

*)

Очевидно, что функции члены класса должны заново комплироваться всегда, когда вносится какое-либо изменение в опсание класса. В идеале такое изменение никак не должно отржаться на пользователях класса. К сожалению, это не так. Для размещения переменной классового типа компилятор должен знать размер объекта класса. Если размер этих объектов меняется, то файлы, в которых класс используется, нужно компилировать зново. Можно написать такую программу (и она уже написана), которая определяет множество (минимальное) файлов, которое необходимо компилировать заново после изменения описания класса, но пока что широкого распространения она не получила.

Почему, можете вы спросить, С++ разработан так, что поле изменения закрытой части необходима новая компиляция ползователей класса? И действительно, почему вообще закрытая часть должна быть представлена в описании класса? Другими словами, раз пользователям класса не разрешается обращаться к закрытым членам, почему их описания должны приводиться в зголовочных файлах, которые, как предполагается, пользователь читает? Ответ – эффективность. Во многих системах и процесс компиляции, и последовательность операций, реализующих вызов функции, проще, когда размер автоматических объектов (объетов в стеке) известен во время компиляции.

Этой сложности можно избежать, представив каждый объект класса как указатель на «настоящий» объект. Так как все эти указатели будут иметь одинаковый размер, а размещение «настящих» объектов можно определить в файле, где доступна закртая часть, то это может решить проблему. Однако решение поразумевает дополнительные ссылки по памяти при обращении к членам класса, а также, что еще хуже, каждый вызов функции с автоматическим объектом класса включает по меньшей мере один вызов программ выделения и освобождения свободной памяти. Это сделало бы также невозможным реализацию inline-функций члнов, которые обращаются к данным закрытой части. Более того, такое изменение сделает невозможным

совместную компоновку C и С++ программ (поскольку C компилятор обрабатывает struct не так, как это будет делать С++ компилятор). Для С++ это было сочтено неприемлемым.

5.3.2 Законченный класс

Программирование без сокрытия данных (с применением структур) требует меньшей продуманности, чем программирование со сокрытием данных (с использованием классов). Структуру можно определить не слишком задумываясь о том, как ее предплагается использовать. А когда определяется класс, все внимние сосредотачивается на обеспечении нового типа полным мнжеством операций; это важное смещение акцента. Время, потраченное на разработку нового типа, обычно многократно окупается при разработке и тестировании программы.

Вот пример законченного типа 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 amp; i) (* i = 0; *) int ok(int amp; i) (* return i«cursize; *) int next(int amp; i) (* return x[i++]; *) *);

Чтобы протестировать этот класс, можно создать и распчатать множество случайных целых чисел. Такое множество могло бы быть результатом розыгрыша лотереи. Это простое множество можно также использовать для проверки последовательности цлых на повторы. Но для большинства приложений тип множество должен быть немного более проработанным. Как всегда, возможны ошибки:

#include «stream.h»

void error(char* s) (* cerr «„ "set: " «« s «« «\n“; exit(1); *)

Класс 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«m) (* int t = randint(n); if (s.member(t)==0) (* s.insert(t); count++; *) *)

print_in_order( amp;s); *)

В программе, для которой требуется два параметра, счечик числа параметров, argc, должен равняться трем, потому что имя программы всегда передается как argv[0]. Функция

extern int atoi(char*);

функция atoi это стандартная библиотечная функция для преобразования представления целого в виде строки в его внуреннюю (двоичную) форму. Случайные числа генерируются с пмощью стандартной функции rand:

extern int rand; // Не очень случайные, будьте осторожны

int randint(int u) // в диапазоне 1..u (* int r = rand; if (r « 0) r = -r; return 1 + r%u ; *)

Подробности реализации класса должны представлять для пользователя весьма незначительный интерес, но здесь в любом случае будут функции члены. Конструктор выделяет целый вектор заданного максимального размера множества, а деструктор освбождает его:

intset::intset(int m, int n)//самое большее,m int'ов в 1..n (* if (m«1 !! n„m) error(«недопустимый размер intset“); cursize = 0; maxsize = m; x = new int[maxsize]; *)

Поделиться:
Популярные книги

Черный Маг Императора 13

Герда Александр
13. Черный маг императора
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 13

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Маяк надежды

Кас Маркус
5. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Маяк надежды

Великий перелом

Ланцов Михаил Алексеевич
2. Фрунзе
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Великий перелом

Сопротивляйся мне

Вечная Ольга
3. Порочная власть
Любовные романы:
современные любовные романы
эро литература
6.00
рейтинг книги
Сопротивляйся мне

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Ох уж этот Мин Джин Хо 2

Кронос Александр
2. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 2

Энфис 6

Кронос Александр
6. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 6