Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 82
Текст из файла (страница 82)
При каких условиях люжно сказать, что А = В? К сожалению, в самом языке нет средств, которые помогли бы ответить на этот вопрос. Разработка типа данных существенно зависит от того, как будут использоваться объекты этого типа. Рассмотрим следующие два опрелеления типов в языке С для стека (згас)с) и множества (зе[): есгисс маек [~пг Террасе, ~пт ОасаПОО], ) Х. У; есгесс еет [~пс ИппЬег1г5ем ~пт эата[100]. ) А. Б; Как видно из этих определений, переменные Х, У, А и В имеют структурно эквивалептпые типы — целое число и массив из 100 целых чисел.
Тем не менее условия, при которых выполняется Х = у и А = В, весьма различны: + Равенство для стеков. Если предположить, что ТОО5[аск обозначает объект данных, расположенный па вершине стека Вага, то эквивалентность Х и У имеет смысл определить следующим образом: 1) Х.Тор51есХ = У Тор5[ась; 2) для всех! межлу 0 иТор51аск-!выполнено: Х.Оата[Ц = У,ОО[а[Ц.
Выполнение этих условий будет означать, что Х и У представляют собой эквивалентные стеки. + Ривенплво для мяожесглв. Если предположить, что ИппЬег]п5е[ обозначает количество объектов данных в множествах А и В, то эквивалентность множеств А и В следует опрелелить так; 1) А.ИОпЬег1п5е[ = В.ИипЬег!О5е[; 2) множествоА.ОО1а[0],.А,Оа[а[ИспЬег!п5е1 - Ц являстсяперестаповкоймножестна В. Оа[а [01..В.
Ое[а [ИппЬег!п501 — Ц, так как порядок расположения элементов множества не имеет значения при определении эквивалентности. Разумеется, на эти определения влияет то, как мы реализуем операции над стеками рпзЬ и рор (то есть добавление элемента в стек и извлечение 6.4. Определения типов 291 его оттуда) и операции над множествами О пзег1 и <1е1ете (аналогичные действия для множеств). Например, если мы реализуем добавление элемента к множеству (то есть операцию 1пзегО) таким образом, что все элементы множества будут расположены в возрастающем порядке (это можно сделать, так как элементами множества являются целые числа), то есть при добавлении каждого нового элемента заново будет происходить сортировка массива Оаьа, то определение равенства для стеков станет применимо и для множеств.
Итак, можно сделать вывод, что в настоящее время не существует механизма формализации определения равенства для сложных структур данных. Поэтому обычной практикой при создании определяемых программистом типов данных является добавление специальных операций для установления равенства между объектами. Следовательно, если вы создаете новый тип данных, например стеки, то вам придется помимо обычных операций добавления и извлечения элемента из стека, очистки стека и возвращения верхнего элемента (рпзц, рор, еерОу и Сор) определить еще и операцию равенства стеков (50асЩца!э), если, конечно, равенство между стеками используется в вашей программе.
6.4.2. Определение типов с параметрами В некоторых языках предусмотрена возможность параметризацни определения типов данных, что позволяет использовать одно и то же определение, подставляя в него различные параметры. Необходимость в параметризации возникает тогда, когда требуется определить множество похожих типов данных. Классическим примером параметров, используемых для определения типов, являются размеры массивов. Предположим, что мы хотим определить тип 5ест<оп как запись, В языке А<)а это будет выглядеть следующим образом: туре 5есшоп 1з гесогв цоох <о<едет, 1оэггос<ог: <п<едег: П озх5ые. <о<едег гапде 0 .100 С1азоцо11: аггау < 1..
1001 от 5<осеп< 1О еов гесогв. Отметим одно потенциальное неудобство такого определения. Здесь список студентов, входящий в объект 5ес01оп, может включать в себя не более чем 100 фа- милий. Если потребуется более длинный список, придется создавать новое опре- деление типа. Параметризованное определение типа 5000100 позволяет ввести параметр Мах51хе, который определяет максимальное количество студентов в группе; Суре 5ес«ао(нах5ые: <о<еде<1 1а гесогв цоое: <о<едет: 1охтгос<ог: 1о<едег: С1аззцые: хп1едег гаоде 0 Мах5ые, С1ахзцо11; аггау <1.,нах5ые1 оГ 5<оеещ 1О: ео« гесогцп 292 Глава б.
Инкапсуляция Такое определение типа позволяет задавать значение параметра Нах5> зе как часть объявления каждой оп дельной переменной типа 5есС)оп: Х: 5есС) оп(100) — задает максимальный размер равным 100; у 5есС)оп!25) — задает максимальный размер равным 25. В языке М) эта концспция получила дальнейшее развитие: параметром может являться и тип данных: втяпаеоге 0гдегеб!сея- 5>9 Суре е1ев уа! 1еввтнап: е1ея " е)вк -> Ьоо1 епб; Огбегет)!тент определен как тип (в М1. тип определяется с помощью ключевого слова з>0патиге), который состоит из следующих компонентов: 1) параметра, имеющего тип е1епт; 2) функции 1еззСЬеп, которая получает два элемента типа е!епт и возвратцает булсво значение.
С использованиелт этой сигнатуры (то есть типа) можно объявлять типы данных следуютцим образом: ГксбЬяат>ЕНИЕ тИПа >ПС>СЕя КаК ВарИаНта ПЕПОта тнна*) втгоссоге >ЬС>Сея: Огбегеб!тея = втгосС Суре е)ея = тпс Гоп 1еввтт:е)ея, ):е1ея) = тт<)) епб; 1*обьквпение типа геа1>тея как варианта вевестВЕннотО типа*) всгостоге геа1>сея: побегем!Сея = вегосС Суре е1ев - геа1; Гоп )еввтт:е!ея, З е)ея) - тт<З) епб: Затем мы можем использовать следующий вызов: - тес>Сея.1еввт5 б); уа) >С = Сгое . Ьоо1 ! пгт Сент.!езз — это функция 1еза, аргументами которой являются целыс числа, что указано в спгпатурс для 1п)С>Сеж Реализация.
Определения типов с параметрами используются прн колшиляции в качестве шаблонов, так же как и остальные определения типов. Единственное отличие заключается в том, что когда компилятор транслирует объявление переменной со списком параметров, следую>цим за именем типа, он сначала вставляет фактическиезначения параметров вопрсделенис типа, чтобы получить полное определение типа переменной без параметров. Используемые в определениях типов параметры влияют на реализацию выполнения программ, написанных на данном языке, только в некоторых немногочисленных случаях (например, когда подпрограмма должна щ>лучать в качестве параметра любой объект данных параметризованного типа и должна быть готова к получению параметра, возможно, иного размера при каждом вызове).
В случае языка М)., в котором можно параметризировать как операции, так и типы их аргументов, фактически можно определить инкапсулированный тип. Мы обсудим вопросы реализации параметризованных типов более полно в главе 7, когда будем рассматривать объектно-ориентированные классы. 6,6. Обзор языка С«+ 293 6.5. Обзор языка С++ История языка. Так жс как и в случае с языком Раэса1, автором которого считается Нпклаус Вирт, созлание языка С++ обычно приписывают одному конкретному чсловеку. Бьсрн Страуструп на основе языка С разработал столь жс эффективный язык, но с некоторыми дополнительными возможностями в области паслсдованпя объсктов.
Для понимания языка С+э желательно, чтобы ужо был изучсн язык С (прнложснис, раздел П.2). В концс 70-х ~т. Страуструп работал над свосй докторской дисгсртацисй в компьнперной лаборатории (Со>про(Ь>8 ЬаЬогагогу) в Кембридже (Англия).
В то время он использовал язык 6!о>п!и (произошедший от Л1.001 ). в котором было ввсдсно понятие классов как объектов данных. С грауструп сделал вывод, что классы, определснные в $шш1а, могут служить эффсктивным механизмом для опредслсния типов. Поступив на работу в компани>о АТ4 Т Вс!1 Тс! ерйопе ЕаЬогатог(сэ в С1ПА, он нсмсдленно начал разрабатывать расширения для языка С, которые включали в себя нскоторыс возможности этих самых классов из Бшш1а. Страуструп руководствовался тем принципом, что всс дополнения, привнесенныс им в язык С, но должны понизить ого эффективность и ста>.ь причиной замсдлсния работы программ. Разработанные им расширения языка С, известныс под названием С п>(гп С1аиеэ (С с классами), содержали основную структуру классов, входящую н сопрсмспцый С++. К 1982 г. ого язык С с классами имел скромный успсх в прсдслах АТ4' Т Вой '!с!ерЬопс 1.аЬогаьоНсч, и Страуструпу, уподобившемуся гуру, приходилось решать все вопросы, связаппыс с поддержкой этого языка.
В концс концов, эта обязанность с>ала для цсго слишком обрсмснитсльпой, и оп пришел к выводу, что у ного ость только две возможности (109]: «1) Прскратить ноддсржку языка С с классами, в рсзультатс чсго сто пользователи 6>удуг вынуждспы псрскл>оч иться на какой-либо другой язык и дадут мне возможность заниматься своими долами.
2) Используя весь накопленный опьп, разработаю иа осповс С с классами новый (более качествсвный) язык, который имел бы коммсрческий успех. Это позволит организовать поддержку и дальпейшсе развитис нового языка на коммсрчсском уровпс и впоследствии такжс даст мнс возможность заниматься своими лолами», Он выбрал второй вариант и усовершенствовал язык С с классами, добавив новые ва>можности, а такжс устранив некоторые несоотвстствия, имсвшисся в этом языке. В 1984 г.
рсзультат его труда получил новос названнс. Одни называли С с классами новым С адругис называли стандартный С старым, или простым С. Нскоторос время испол> зовалось назвацис С84, азатом Рик Маски >ти (Ысэ Маэс>нь() иэ Вс1! 1лЬэ предложил название С~-~. В этом названии используется обозначение э+ опсрации увеличения на единицу в языке С, которос в данном случае озпачаст «следуюп>ий>ч .и>- следователью Название С«э многократно обы~рывалось в различных каламбурах и служило поводом для многочисленных шуток (см, врезку «Обзор языка 6,1ь).