- •4.9.1. Изменяемость
- •4.9.2. Классы операций
- •98 Глава 4
- •4.9.3. Полнота
- •100 Глава 4
- •4.9.5. Операции egual, similar и copy
- •102 Глава 4
- •104 Глава 4
- •5. Исключительные ситуации
- •108 Глава 5
- •110 Глава 5
- •6.2.1. Сигнализация об исключительных ситуациях
- •5.2.2. Обработка исключительных ситуаций
- •112 Глава 5
- •5.2.3. Предложение resignal
- •6.2.4. Необрабатываемые исключительные ситуации
- •114 Глава 5
- •6.2.3. Предложение resignal
- •5.2.4. Необрабатываемые исключительные ситуации
- •116 Глава 5
- •118 Глава 5
- •118 Глава 5
- •120 Глава 5
- •122 Глава 5
- •124 Глава 5
- •128 Глава 6
- •130 Глава 6
- •6.2.1. Реализация итераторов
- •6.2.2. Использование итераторов
- •132 Глава 6
- •134 Глава 6
- •136 Глава 6
- •138 Глава 6
- •140 Глава 7
- •142 Глава 7
- •7.2. Абстракция данных
- •144 Глава 7
- •146 Глава 7
- •148 Глава 7
- •150 Глава 7
- •7.4. Генераторы
- •162 Глава 7
- •154 Глава 7
- •156 Глава 7
- •162 Глава 8
- •164 Глава 8
- •166 Глава 8
- •168 Глава 8
- •170 Глава 9
- •172 Глава 9
- •174 Глава 9
- •176 Глава 9
- •9.1.3. Пример
- •178 Глава 9
- •180 Глава 9
- •182 Глава 9
- •184 Глава 9
- •186 Глава 9
- •188 Глава 9
- •190 Глава 9
- •192 Глава. 9
- •194 Глава 9
148 Глава 7
Рис. 7.4. Очереди ql и q2 не используют совместно одну и ту же очередь.
а совместное использование все равно правильно бы paбo^aлo.
Часто бывает полезным включить в "тип некоторую функцию копирования, например функцию q_copy с определением, приведенным в гл. 4. Функции копирования должны обеспечивать полную неразделяемую копию аргументов. Они могут быть использованы всегда, когда мы хотим выполнить присвоение обычным семантическим правилом языка Паскаль. Например, мы могли бы написать ql: = q_copy (q2), а не ql: = q2. На рис. 7.4 показано отсутствие совместного использования в том случае, когда очереди ql присваивается значение функции q.copy (q2). Надо иметь в виду, однако, что эти функции копирования не будут вызываться компиляторами как часть неявного присваивания, например, при обращении по значению.
И наконец, отметим, что наш метод не препятствует тому, чтобы программы получали доступ к представлению вне реализации некоторого типа. По нашему соглашению мы просто считаем такой доступ не по правилам.
7.3. Полиморфные абстракции
Параметры типа языка CLU позволяют нам построить полиморфные абстракции, т. е. абстракции, которые могут быть использованы для объектов различного типа, В языке Паскаль имеется некоторый встроенный полиморфизм. Генератор типа массивов, например, может быть использован для объявления массивов с различными границами и элементами различных типов. Однако в языке Паскаль почти не обеспечивается определенный пользователем полиморфизм. Конечно, это не остановит нас перед проектированием полиморфных абстракций. Спецификация таких абстракций достаточно очевидна. Мы используем синтаксис, аналогичный тому, который использовался для специфи-
Использование. языка Паскаль
queue = data type retype: type] is q [etype]_new, q [etype]Jsempty, q [etype]_append, q [etype]_remiirst, q [etype].destroy
Описание
Очереди используются для хранения значений типа данных etype. Элементы могут извлекаться из очереди или удаляться из нее только методом обратного магазинного типа («первым пришел — первым обслужен»).
procedure q ietype]_append (q: queue [etype]; e; etype) modifies q efiects Добавляет элемент e в конец очереди q.
end queue Рис. 7.5. Частичная спецификация параметрической счереди.
кации параметрических абстракций при реализации на языке CLU. Пример параметрической очереди приведен па рис. 7.5.
Поскольку язык Паскаль не обеспечивает реализацию параметрических абстракций, мы опять полагаемся па соглашение по программированию. Реализация параметрической очереди может выглядеть совсем как реализация inna данных intqueue. Объявление типа представления приводится на рис. 7,6.
type
queue [etypeJ == I queue [etype ]_rep; queue [etype ]_rep == ]quew [etype]_eleiT]; queue [etype ]_e!em == record val: etype; next: queue [etype ]_rep; end;
Рис.. 7.6. Тип представления для реализации типа queue [ etype].
Эти объявления не верны в смысле языка Паскаль, поскольку они содержат такие неверные идентификаторы, как queue letype!. В реализацию этих операций мы вводим также синтаксические ошибки. Эти синтаксические ошибки предотвращают оттого, чтобы программисты случайно не использовали нереализованные параметрические абстракции. Реализация операций аналогична реализации, приведенной на рис. 7.2, за исключением того, что префикс q заменяем на префикс queue [etype!, а идентификаторы intqueue и integer—соответственно на queue letype] и etype. Реализация операции q letypeLappend приведена на рис. 7.7.
Прежде чем использовать в программе реализацию типа данных queue [etype], мы должны использовать редактор текстсв, чтобы заменить каждое вхождение текста queue [etype] на неко-чорый удобный незапрещенный идентификатор, например на intq. Кроме того, надо заменить все оставшиеся вхождения иден-тификачора etype на некоторый уже известный тип, например
