Р.У. Себеста - Основные копцепции языков программирования (2001) (1160794), страница 115
Текст из файла (страница 115)
Примеры абстракции данных в разных языках ра зля обьекза вг'к. В результате массив. являющийся частью объекта типа эсас)<, уда- ляс<ся пз памяти. 10.5.3.4. Оценка ((оллсржка в языке С + абстрактных типов данных с помощью конструкции класса по выраштельности сравнима с поддержкой абстрактных типов ланных в языке А<(а с помоп<ью пакетов. Оба языка обеспечивают аффективный механизм инкапсуляции и сокрытия данных общих типов. Основное различие л<ежду ними заключается в том, что ллассы являюзся типами.
а пакеты в языке А<(а — инкапсуляциями. Кроме того, понятие класса оыло разработано не только для абстракции данных, что обсуждается в главе ! !. () ша <и проблем разрабозки языка. вытекающая из наличия классов и отсутствия об< нпс<шой нньапсуляц<и<.
состоит в том, что не всегда ес<сствснно связывать операции объс< г. с о<дельными объектами. Например, предположил<. что. имея абстрактные типы данны< зля матриц н велторов, необходимо< определить операцию умножения матрицы на вектор. В какой к<асс следует поместить зту операцию". В языке С+ ситуации такою зина разрешаются с помощью назначения функции, внешней по отношению к классу, его "яру<о«'1 Функции-друзья имеют доступ к закрытым сущностям класса, другом которого опи объявлены.
Для умножения матрицы на вслтор в языке С++ одним из решений яаляс гся описание операции вне ю<ассов матрицы и вектора и обьявление ее другом обоих классов. Следующий скелетный код иллюстрирует этот сценарий: с1аээ Нас 'к; //' Объявление класса с1вээ 'ес'ог хкьепс( Чес<ог жц1Г)р1у(сопвс Магг1хь, сопев Честога); с1ввв Мнгг!и < //'* Огределение класса екзепс( чесгюг жо1сдр1у(сопев масгдха, сопвк чессога) .,иксия, использующая объекты классов Ма"гдх и Чессог с1С'р'у',сопвс Маггдха з<', сопвк Чесаога ч!) ( Н иьприцу, и вектор можно бьшо бы описать в пакете на языке А<(а, избежав подобноь пр<х>лемь<. фоме функций. друзьями класса могут быть объявлены целые классы, тогла все за.ры ыс члены класса будут видимы всеми членами лружественных классов.
10.5.3.5. Родственный язык Мозга ! й<дзержка абстракзных типов данных в языке 1ача почти такая же, как и в языке С- ° !. и. однако. несколько важных различий. Все типы данных. определенные нользояш«лом в языке 3ача. являются классами. и все объекты размещаются в динамической шкив <и, а доступ к ним осуществляется с помощью ссылок. Другое различие межлу поп.<ерело« абстрактных типов данных в языках Зача и С++ заключается в том, что подпро< раммы (методы) в языке Зача могут быть описаны только внутри класса.
Таким образоч. я классах языка Зача нельзя помешать заголовки функций без их тел. Глава 1О. Абстрактныв типы данных В языке )ача зарезервированные слова ркьчаее и риЬ11с являются лишь молифи- :-срами, которые могут быть присоединены к определению переменной или метода. но - л не определяют закрытые и открытые разлелы в описании класса. В то время как в языке С++ классы являются единственным способом ннкапс)ляпни, - ~зыке )ача есть и другой способ (уровнем выше, чем классы) — пакет, Пакеты могут .:=ержать несколько определений класса, и классы в пакете являются "частичными" "' зьями.
Слово 'частичные" здесь означает, что элементы класса в пакете. о~крытые -и защищенные (см. главу ) )), либо не имеющие спецификатора доступа, являются внмычи во всех других классах в пакете. Сущности без спецификаторов доступа назы- гзотся сущностями, нмеюшимн пакетную область видимости (расйаяе зсоре). по- ольку они видимы внутри пакета. По этой причине язык )ача не нуждается в явных ьявлениях друзей и не содержит дружественных функций или лружественных классов.
.к а языке С++. Пакеты, которые часто содержат библиотеки. можно описывать иерарчески. Стандартные библиотеки классов языка 3ача определяются в виде иерархии па- в.ов, Область видимости пакета обсуждается далее в главе ) ). Ниже приводится опрелеление класса на языке )ача для нашего примера стека. ьврокс Эача.1о.*) с1аее ЯСаск с1аяя ( ркйчаев дпе [] аеас)с кейз ркдчаее дпк вах 1еп, Тор 1пс)ех( риЬ11о ЯСаск с1аяя() ( // Конструктор ясас3с кей = пен дпс [100]; пах 1еп = 99; сор 1пс(ех = -1; рцЫйс чоьс) рцяЛ (дпе пцвЬег) ( дй( ор 1пс(ех == вах 1еп) Яуяеев.оцт.рг(пС1п("Ошибка в функции рцяЬ вЂ” стек попсе",'; е1ве яеасй сей[++Сор Япс)ех] = пивЬег( риЬ11с чодй рор() ( дя (сор 1пс(ех == -1) ЯуяСев.оце.рсупС1п("Ошибка в функции рор — стек пуст") е1ве — сор дпбех; ) риЫдс дпс сор() ( кесикп (ясаск геб [сор фпс(ех] ); ) риЫ1с Ьоо1еап еврСу() (кесикп (Сор 1пс(ех == -1);) Рассмотрим пример класса.
который использует класс ЯСаск с1аяя. рмЬ11с с1аве ТяС ЯСаск ( риЫас веаедс чозс( ваап(ЯСтфпд[] аг9я) ЯСаск с1аяя вуЯСас)с = пен ЯСасх с1аяя(); вуЯСасх.оцяЬ(42); вуЯСаск.рцяЬ(29)З яуясев.оцс.ргзпс1п(" 29 : " + вуясас)с.сор()); вуЯСас)с.рор(); яуяСев.оцс.рг'гС'и(" 42 : " ~ вуЯСасй.'сор()); 10.5. Примеры абстракции данных в разных языках туЯсас1с.рор()г щуЯсас)с.рор()з // Порождает сообщение сб ошибке ) Стек — неудачный пример лля языка )ача, поскольку библиотека языка )ача уже содержит определение класса для стеков.
Однако наше определение класса для стеков позволяет сравнить его реализацию в языке )ача с реализацией в языке С++ из раздела 10.5ли Одно из очевидных отличий заключается в отсутствии деструктора в )атаверсии, необходимость в котором отпадает, так как в языке ]ача используется механизм неявного освобождения памяти. Другое значительное отличие состоит в использовании ссылок (а не указателей) для адресации объектов типа з(ас)с. 10.6. Параметризованные абстрактные типы данных Часто бывает удобно параметризовать абстрактные типы данных.
Например, нужно иметь возможность разработать абстрактный тип данных для стека, в котором могут храниться элементы любого скалярного типа, а не писать отдельные абстракции стека для каждого скалярного типа. В следующих двух подразделах описываются возможности, предусмотренные в языках Ада и Сч-ь для конструирования параметризованных абстрактных типов данных. 10.6.1.
Язык Адсз Настриваемые процедуры в языке Ада обсуждались и иллюстрировались в главе 8. Пакеты также могут быть настраиваемыми (зепепс), так что мы можем конструировать и настраиваемые, или параметризованные, абстрактные типы данных. Пример абстрактного типа данных для стека в языке Ада, приведенный в разделе 10.5.2, имеет два ограничения: 1) стеки этого типа могут хранить только элементы целого типа; 2) стеки могут иметь только до 100 элементов.
Оба этих ограничения можно отменить, используя пакет, на основе которого можно создавать экземпляры для других типов элементов и любого желаемого размера. (Это — настраиваемое создание экземпляров, которое очень отличается от создания экземпляра класса при создании объекта.) Приведенная ниже спецификация пакета описывает интерфейс настраиваемого абстралтного типа данных для стека с указанными свойствами: депегхс ИАХ Я1ЕЕ : РОЯ1Т1]/Ег -- Настраиваемый параметр — размер стека Суре ЕЕЕМЕНТ ТУРЕ дв ргдзгагег -- Настраиваемый параметр— тип элемента рас]саде ЯЕНЕН1С ЯТйСК Ев Видимые сущности, или открытый интерфейс гуре ЯТАСКТУРЕ хв 1зщдгес( ргзчагег Ецпскдоп ЕИРТУ(ЯТК : дп ЯТАСКТУРЕ) гесигп ВООЬЕАН] ргосес)иге РОЯН(ЯТК : Зп оис ЯТАСКТУРЕ; ЕЕЕМЕНТ : Дп ЕЬЕМЕНТ ТУРЕ); ргосейиге РОР(ЯТК : хп пик ЯТАСКТУРЕ); Еипсгдоп ТОР(ЯТК : Еп ЯТАСКТУРЕ] гесигп ЕЬЕМЕНТ ТУРЕ; Скрытая часть Глсас 10.
Абстрактные типы данных рггваФе гуре ЫЯТ ТУРЕ Ев аггау (1..МАХ Я12Е) оЕ ЕЬЕМЕМТ ТУРЕ; гу)ре ЯТАСКТУРЕ Ев з ЫЯТ: Ь1ЯТ ТУРЕг ТОРЯОВ: 1ИТЕОЕР, гапде О..МАХ Я12Е := О) ( з) еп6 ЯЕ(ЧЕА1С ЯТАСК; Тело пакета ОЕНЕВ1С ЯТАСК такое же, как и тело пакета ЯТАСКРАСК в прелыду:и разделе, за исключением того, что формальный параметр ЕЬЕМЕИТ в функциях :..'Я;-1 и ТОР имееттип ЕЬЕМЕНТ ТУРЕ вместо типа 1ИТЕОЕР,. Следуюший оператор создает экземпляр пакета ОЕИЕА1С ЯТАСК для стека. со-оящего из 100 элементов типа 1МТЕЯЕГО рао)саде 1МТЕОЕК ЯТАСК Ев пвм ЯЕИЕй1С ЯТАСК(100, 1ЛТЕОЕВ); Можно также построить абстрактный тип данных для стека, состояшего нз 500 эле° титов типа Г1.ОАТ, как показано ниже: рао)саде ГЬОАТ ЯТАСК Ев пвм ОЕ)(Ей1С ЯТАСК(500, ГЬОАТ) Эти примеры создания объектов порождают две различные версии исходного кола -зкета ОЕИЕВ1С ЯТАСК во время компиляции.
10.6.2. Язык С++ Язык Сть также поддерживает параметризованные, илн настраиваемые, абстрактные - глы данных. Для того чтобы сделать пример класса лля стека в языке С+в из гюзела 10.5.3 настраиваемым по размеру стека, нужно изменить только конструктор, зк показано ниже: згас)с(дпг ззге) ( ас)с рсг = пем 1по [в1ге) мах 1еп = в1ге — 1; Сор = -1; Объявление объекта типа всас)с теперь запишем так: згаск (150) вСХ) Определение класса всаск может содержать оба конструктора, так что пользователь :пользует размер стека по умолчанию или указывает какой-нибудь другой размер. Тип элементов в стеке можно превратить в параметр, сделав класс шаблонным.
Тогда - з элементов может быть шаблонным параметром. Определение шаблонного класса - .ла зшс(с приведено ниже. =1пс1ис)е <Ьовсгеаа.)з> гвар1агв <о1авв Туре> // Тип является шаблонным параметром о1авв втаск ( ргзмаге: Туре *атас)с ргг; з.пс пах 1еп; ', О.Ь. Параметризованные абстрактные типы данных апк Сор рсг) рпЬ11с: // Конструктор для стека из 100 элементов ясаск() ( я1ас)с ргг = пви Туре [100]; гах 1еп = 99) сор рсг = -1; ) // Констоуктор для стека из заданного количества элементов агасси(1пс я1ге) ( ягас)с ргг = пви Туре [я1хе]' шах 1еп = ядзе — 1; сор рсг = -11 ) -агаси() (ав1всв ясасх рсг;»; // Деструктор чодс) рцяЬ(Туре пцшЬег) ( ах(гор ргг == шах 1еп) соцс « "Ошибка в функции рая)з — стек полон'1п"г в1ев ясасй рсг[~+Гор ргг] = пцшЬег; ) чодй рор() ( 1Г(сор рсг == -1) соцс « "Ошибка в функции рор — стек пуст'1п"; в1вв Сор ргг--: 1 е гор() (гвкигп (ягасй ртг [сор Рсг) ) ) г дпк ег1ргу(] (гвсигп (сор рсг == -1) ) 1; Как н в языке Лба, экземшзяры шаблонных классов в языке С++ создаются во время комп1щяции.
Отличие состоит в том, что в языке С++ создание экземпляра является неявным: создание экземпляра происходит каждый раз при создании нового объекта, что треоу ет наличия версии шаблонного класса, которой пока не существует. ! )оиятие абстрактных типов данных и их использование в разработке программ было ключевым моментом в развитии программирования как технической дисциплины. Несмотря на то что это понятие относительно простое, его использование стало удобным и безопасным только после разработки языков для его поддержки. Инкапсуляция является единицей компиляции, которая содержит набор логически связанных типов, объектов и подпрограмм.