Лекция 14 (лекции (2002))

2019-09-19СтудИзба

Описание файла

Файл "Лекция 14" внутри архива находится в папке "лекции (2002)". Документ из архива "лекции (2002)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "Лекция 14"

Текст из документа "Лекция 14"

Лекция 14

АТД, где единицей и атомом защиты является весь ТД присутствует в Аде, Модуле-2 и, частично, в Delphi, в которых есть понятие модуля, пакета, модуля описаний и модуля определений. В Delphi это unit и тут единица защиты, как во всех языках является целиком ТД. Но атом защиты в них- тоже тип целиком, то есть создатели этих языков поддталкивают писать нас в терминах АТД, так как это хорошо.

В Аде limited private- настоящий АТД. К нему применимы: передача, как параметры; самые базовые- узнать размер типа, узнать адресс переменной; операции, описанные ниже в спецификации пакета, после определения его имени:

type T is limited private;

операции

private

type T record ... end record;

Запрещены операторы «:=», «=», «/=» и так далее. Тут структура нужна в спецификации пакета из соображений гибкости, для эффективного распределения памяти компилятором. Так же в Аде есть зачаточные возможности инициализации записи (size = 25). И при размещении объектов типа Т в памяти компилятор вставляем минимальный инициализационный код. Но структура доступна только компилятору.

В Модуле-2: TYPE T; - это либо указатель, либо совместимый с ним ТД, что заставляло программировать нас в парадигме исключительно динамических ТД.

В Delphi есть как модульная парадигма так и парадигма классов и мы увидим, что к нему относится и всё, что мы говорили про Аду и Модулу-2 и всё, что мы будем говорить про языки с классами.

Оберон: немного другая идеология. Это ещё один модульный язык. Вместо того, чтобы целиком закрывать или открывать тип данных (атом защиты- ТД целиком), тут используется понятие «проекция»:

MODULE M;

TYPE T* = RECORD

'*'- если хотим экспортировать это имя. Мы открываем или закрываем доступ к отдельным элементам записи:

X* : INTEGER; /* поле видимо */

Y : REAL; /* поле не видимо */

END;

В Обероне ещё присутствует «*-» - доступ только на чтение (применима только к имёнам объектов данных, но не к процедурам или функциям).

IMPORT M;

Z : M.T; - это проекция

В Обероне есть утилита, генерирующая псевдофайл определений. В псевдомодуле определений автоматически сгенерируется:

DEFINITION M; // это не ключевое слово языка Оберон

TYPE T = RECORD

X : INTEGER;

END;

Это как бы проекция Т. А что если вообще внутри типа не писать ”*” ?

TYPE C* =

RECORD

x,y,z : X1;

d : X2;

END;

Что будет сгенерировано в псевдомодуле определений?

TYPE C = RECORD END;

Пустая запись. С точки зрения языка С пустая запись- это извращение, а с точки зрения Оберона: это АТД. Но как и в Модуле-2 тут мы не можем более тонко управлять поведением АТД, как мы могли сделать в Аде (разрешать/не разрешать операцию присваивания, например, когда нас не устраивает обычное побитовое копирование, мы делает тип ограниченным приватным типом о операцию копирования просто переопределяем как новую дополнительную операцию). В Обероне тем не менее есть некоторое приближение к АТД и оно лучше, чем то, что было в Модуле-2, хуже с точки зрения гибкости чем в Аде, но зато существенно проще: никаких особых новых концепций, кроме понятия видимости и понятия проекции для этого мы не вводим. Возникает интересный вопрос: «А всё-таки кто-то знает эту структуру?». Компилятор, конечно, знает структуру, когда он транслирует модуль, то всю информацию оставляет в некотором бинарном табличном файле (скорее всего). И когда мы пишем « IMPORT M; Z : M.T;» компилятор знает, что ему нужно отводить память не под переменную типа Х,а под некую запись размера INTEGER и REAL, соответственно. Следовательно по эффективности распределения памяти Оберон не уступает языку Ада. Так как компьютеры стали мощьнее, а это решение, как мы увидим в следующей главе приводит к некоторым накладным расходам.

В современных ЯП более гибкие средства управления доступом (видимостью), то есть так как нас заставляют писать в терминах АТД мы приходим к более гибким схемам.

Современные ЯП: атом защиты- отдельный член класса. Рассмотрим С++, так как здесь более простая схема и все остальные схемы (Java, C#, Delphi) просто несколько обощают общую схему языка С++, а она очень проста.

C++: два способа группировки (объектов, типов данных, констант и так далее):

класс- логический модуль

файл- физический модуль

{Существует ещё понятие проекта, пространства имён. Понятие проекта на уровне языка С/C++ не выступает, а с физической точки зрения пространство имён реализуется как некоторая совокупность файлов, но об этом несколько позже}

В файл остались средства управления видимостью, которые перешли из языка С, в который он перешли из ассемблера: существуют внешние имена и внутренние:

static статические //локально в файле

extern внешние //он подразумевается по умолчанию- она (переменная или функция) видима извне этого файла)

Это немного похоже на имена из модуля определений (внешние) и модуля реализации (внутренние).

Класс:

public видимы абсолютно всем, кто видит этот класс (доступно всем)

private видимы только функциям членам этого класса (доступно себе)

Есть ещё и

protected видимы в функциях членах этого класса, а так же в функциях членах унаследованных классов, то есть доступно себе и детям (появилось из-за наследования)

Синтаксически это выглядит как переключатель:

class X {

public:

X();

~X();

private:

...

}

По умолчанию в класса доступ private, а в структуре public. Они только этим и отличаются.

Довольно простая схема, но не всегда удобно. Пример:

class Matrix {

...

public:

...

};

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

Matrix& operator+(Matrix &M);

{передаётся this, он и выступает в качестве первого члена}

a+b ~ a.operator+(b);

Здесь чёткая несмимметрия: первый аргумент как бы сильнее втого, всё исходит из него. К томуже эта операция (математический плюс) должна быть без побочного эффектка, не должна модифицировать как первый так и второй аргументы (а в таких операциях обычно возвращается певый аргумент), должна возвращать третье значение. Поэтому, вообще говоря, если операция имеет ясный математический смысл, который по семантике совпадает со смыслом заложенным в сам язык (в противном случае операторы не рекомендуется переопределять, лучше придумывать для них свои имена), то, с точки зрения операции плюс, это должна быть операция без побочного эффекта, симметричная относительно своих операндов, возвращающая третье значение. А вот модифицирующая операция в С/C++ a+=b – это рекомендуется переопределять как функции члены они модифицируют свой левый аргумент. И поэтому её имеет смысл переопределить как одноместную функцию член соответствующего класса. И это будет интерпретироваться как «a.operator+=(b);». И, естественно, модифицирует свой первый операнд и его же возвращает в качестве своего значения. А a+b разумно переопределить как внешнюю функцию. Но тут-то и возникают проблемы: раз это внешняя функция, то она имеет доступ только к публичным членам данных. Следовательно для эффективной реализации надо либо отказаться от инкапсуляции, либо придумать какой-то другой механизм. Он придуман, а именно, механизм «друзей». В некоторых случаях совершенно необходимо отдельным внешним функциям дать особый доступ, то есть приравнять внешнюю функцию к функции члену этого же класса (для которых нет никаких ограничений на доступ).

Должны быть внешние функции. Операция, применимая к двум классам (Х1 и Х2): либо внешняя функция к Х1 и Х2, либо глобальная, либо функция-член одного класса из этих классов. В любом случае для одного из этих двух классов эта операция будет являться внешней и в тоже время она должна иметь общий доступ. В Обероне, Аде, Модуле-2 это не проблема, мы просто определение типов Х1 и Х2 сводим в один и тот же модуль и там же описываем все операции, в том числе и эту, так как в модуле можно определять и несколько ТД и это более общее понятие чем для отдного ТД, и всё, что мы в нём описали имеет доступ ко всем типам, описанным в этом модуле, не важно скрытые они, приватные или как-то ещё. Поблем нет. А как только возникает понятие класса, тесно связанное с ТД нам нужны специальные средства, дополнительные средства, управления доступом. В С++ это средство называется другом класса. Друг- это функция или класс, которые описаны либо в другом классе либо глобально.

class Matrix {

friend Matrix& operator+(Matrix& a, Matrix& b);

/* friend (функция плюс) имеет полный доступ ко всем членам (эквивалентен функции члену по доступу). */

friend void Y::f();

/* так же может быть отдельная функция другого класса */

friend class Z;

/* все функции класса Z являются друзьями этого класса /

}

Дружбу объявляют явно. В друзья не набиваются, в друзья берут. Отношение дружественности не транзитивно (класс Х берёт себе в друзья класс Y, а класс Y берёт себе в друзья класс Z, из этого не значит, что Z будет неявно другом Х) и не наследуется (если класс Х объявил, что Y- его друг; мы вывели из класса Х некоторый класс Z; или, соответственно, наоборот, из Y вывели какой-то тип данных Т; из этого не значит, что Z, то есть те новые члены, которые мы добавили к классу Х, мы разрешаем для Y доступ; то же самое: класс T имеет все функции члены класса Y, которые имеют доступ к Х, но не новые функции члены класса Т. Аналогия с человеческими отношениями. Отношение дружественности достаточно безопасно и при этом позволяет решить много проблем. И при этом друзья могут быть произвольными внешними функциями или классами.

Эта схема перешла в C#, Java, Delphi. Но они её немного расширили. Основная проблема С/C++ в слабости его файловой структуры (раздельной трансляции). Только два способа группировки: сам класс и файл. Но понятия «проект» или «подпроект» не существует на уровне языка С/С++. Недаром сразу же как только был разработан компилятор с языка С появилась утилита make, которая и показывает какие файлы входят в проект и как ими управлять. Проект (логически сгруппированная совокупность файлов)- ещё одно средство группировки. Это и используют языки, которые унаследовали С++.

Похожие понятия: пространство имён C# (сильно отличается от С++ понятия) и пакет Java имеют иерархическую структуру. С точки зрения операционной системы (реализации этих языков) эти иерархические структуры отражаются на иерархическую структуру файловой системы (директории, поддиректории и так далее). Это некоторый физический способ на уровне языка группировки файлов в проекты. И этим механизмом вполне естественно воспользоваться для управления видимостью, а точнее- доступом.

В Аде (как и в Обероне) речь идёт об управлении видимостью, а в языках типа С++ (ООЯП) речь идёт об управлении доступом (приватное имя видимо, но достать его нельзя). Разница появляется при наследовании.

В Delphi кроме проекта появляется ещё и понятие unit (модуль), и им естественно воспользоваться для управления видимостью в пределах класса.

Во всех этих ЯП есть:

private - по умолчанию (если нет ключевого слова) в С++

protected

public

Кроме этого ещё один вид доступа:

C#: internal - по умолчанию (внутренний доступ)

Java- по умолчанию пакетный доступ (с точки зрения одного пакета публичный доступ, а с точки зрения всех остальных приватный доступ), для него нет никакого ключевого слова. Внутренний доступ в языке С# аналогичен пакетному, только в рамках одного пространства имён, а не пакета. Например, если у нас есть оператор op(x1, x2), то x1 и x2 должны принадлежать одному пакету, тогда х1 и х2 мы просто описыванием как внутренние.

В Delphi аналог пакетного доступа:

unit

type X = class

операции

данные

...

По умолчанию и операции и данные имеют пакетный доступ- к ним имеют доступ все классы и функции из unit’a (Тут ещё есть интересная тонкость Delphi- динамический доступ, но мы его касаться не будем).

Пространство имён Х. Тип данных Т (в нём внутренние или пакетные данные). Пространство имён Y : импортирует Х и там из Т выводится Т1. Какой доступ у функций членов класса Т1. К приватным никакого. К защищённым по определению имеется. А вот к внутренним? В С#: существует protected internal, которое соединяет эти два понятия, но это уже некоторые навороты.

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5224
Авторов
на СтудИзбе
426
Средний доход
с одного платного файла
Обучение Подробнее