лекция 20 (1161115)

Файл №1161115 лекция 20 (Языки программирования (лекции) (2008))лекция 20 (1161115)2019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла

Глава 2: Динамическое связывание (продолжение)

В прошлый раз говорили про организацию виртуальных методов (таблица виртуальных методов фактически это неявный статический член виртуального класса).

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

Классовые языки

В языках ориентированных на классы динамическое связывание очень похоже на Си++, есть определенные нюансы.

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

В Си# и Дельфи есть как виртуальные методы

Виртуальные методы описываются:

1.Cи#:

virtual void f() {...}

2.Delphi:

procedure F; virtual;

2.

Если в Си++ метод является виртуальным и объявлен как виртуальный, то стать невиртуальным он уже не может!

class X {

int f();

virtual void g();

}

class Y public X {

void g();

virtual int f(); // не имеем право так делать

}

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

И в языках Си# и Дельфи этих ограничений нет. Чтобы подменить функцию, надо это явно указать:

1.Cи#: override void f() {...}

2.Delphi: procedure F; override;

Если ключевого слова override не стоит, то это считается, что такие функции закрывают соответствующие виртуальные предыдущие функции, и после этого механизма виртуального вызова не будет. Хотя из производных классов потом можно будет унаследовать виртуальную функцию void f(), сделав ключевое слова override. Функция может быть виртуальной, потом стать невиртуальной, а потом снова может стать виртуальной, если мы это укажем явно. С точки зрения практического программирования это исправление недостатков существующих иерархий классов, которых программист поменять не может. С точки зрения дизайна собственных классов применение таких трюков некрасиво. В остальном механизм динамического связывания работает как в Си++.

Неклассовые языки

(Ада 95 и Оберон-2):

Оберон.

В Обероне (1988 год, Оберон 2 появился окончательно в 1993 году) было наследование (расширение типа), но не было динамического связывания (оно реализовывалось при помощи специальных обработчиков - вместо виртуального метода мы создавали поле функционального типа данных, и при инициализации экземпляра каждого типа мы должны были нужной функцией инициализировать нужное поле)1.

С точки зрения ООП объект класса представляет:

- члены-данные (определяют текущее состояние объекта класса);

- члены-функции (определяют поведение экземпляра объекта класса;)

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

SmallTalk. В этом языки динамическое поведение может динамически меняться в зависимости от того, что мы сделали с соответствующим типом. В SmallTalk все методы связаны динамически. Мы говорили, что наличие ТВМ позволяет свести поиск виртуального метода к 6-7 ассемблерным командам, поскольку мы знаем профиль каждого метода и знаем смещение адреса этого метода в ТВМ. В SmallTalk совершенно другая ситуация - там цепное распределение памяти.

Х

Объект базового класса

У

Объект производного класса

Z

Ссылка на объект суперкласса

Видим иерархию их 3-х классов, каждый объект содержит свой указатель на ТВМ.

Замечание: Если для такого яп как Си++ (или Java) для производного класса У ТВМ напоминает сам объект (поскольку при наследовании объект класса У содержит часть для Х и часть для У), то же самое и для ТВМ класса У – она в начале содержит таблицу методов для класса Х (ТВМ Х), а потом функции, которые добавлены в классе У. Если соответствующая функция подменяется в классе У, то меняется соответствующий адрес в ТВМ (ТВМ у нас как бы наследуется).

В SmallTalk:

Х

Ссылка на ТВМ для Х

У

Ссылка на ТВМ только для добавленных в классе У

Z

Ссылка на ТВМ только для Z

Как осуществляется поиск виртуального метода? Когда мы вызываем для Z функцию z.f(), то объекту z посылается сообщение f (в терминологии SmallTalk).

Замечание: В языке Java (или Си#, Си++) мы знаем, что для ТВМ этого класса обязательно где-то должен найтись адрес этого обработчика. Наша задача добраться только до ТВМ этого класса, поскольку они у нас наследуются.

В SmallTalk мы сначала ищем соответствующий обработчик в ТВМ Z, потом если мы там не нашли, то идём к нашему родителю и в его ТВМ ищем эту функцию, если и там нет, то идём к родителю нашего родителя и т.д. (пока не дойдем до корневого класса в иерархии, если не нашли, выдается сообщение об ошибке). Это влечёт большие накладные расходы, но что-то там нам всё-таки даёт. В SmallTalk сделана достаточно хитрая вещь, ТВМ – ее можно пополнять и изменять динамически, поэтому есть возможность осуществлять динамический поиск. Когда мы меняем ТВМ, мы меняем его для всего типа в целом, а вовсе не для экземпляров.

Оберон 2.

Язык Оберон-2 - это то же самое, что и Оберон, но с небольшими изменениями, самое главное из которых – появление процедур динамически привязанных к типу.

В Обероне нет понятия перекрытия операций, т.е. одному имени водной области видимости может соответствовать только одна сущность. Для процедур динамически привязанных к типу это уже не совсем так. Если у нас есть какой-то тип:

TYPE T = RECORD

...

END;

Поскольку можно наследовать любой тип данных:

T1 = RECORD (T1)

...

END;

Синтаксис процедуры динамически привязанной к типу:

PROCEDURE (VAR X:T) Draw(); // Draw – это имя, обратите внимание, что оно находится не сразу после

ключевого слова Procedure

X - аргумент - ссылка или указатель. И точно так же динамическая привязка осуществляется не для объектов типа, а только для ссылок или указателей.

В одной и той же области видимости мы можем описать другую процедуру Draw:

PROCEDURE (VAR X:T1) Draw(); // заметим что здесь должен быть объект Х – унаследованный от Т1

Как вызывается соответствующая вещь? Пусть у нас есть нединамическая процедура:

PROCEDURE P(VAR A:T) //нединамическая

BEGIN

A.Draw();

END;

У процедуры динамически привязанной к типу есть один выделенный аргумент – ссылка на объект. Вызов процедуры динамически привязанной к типу даже синтаксически один в одни соответствует вызову методу в яп, ориентированных на классы: A.Draw(). Поскольку речь идет о ссылке (var – переменная передается по адресу), а ссылка обладает динамическим типом. В зависимости от того, какой динамический тип имеет А, будет вызвана соответствующая Draw().

VAR B:T;

B1:T1;

P(B); (* будет вызван T.Draw *)

P(B1); (* будет вызван T1.Draw *)

Замечание: Очень часто получается, что вызываемый виртуальный метод обращается к своему аналогу из базового класса.2 Для этого нужны специальные языковые средства.

  • В Си++ квалификация имени класса: имя_класса::имя_функции

Этот механизм снимает виртуальность вызова, он четко говорит, что нужно вызвать имя функции из такого-то класса. Такое можно применять только внутри функций самого класса, потому что вначале по умолчанию приписывается this->. Если мы вызываем функцию извне, мы должны явным образом указать соответствующий класс.

P.X::F //Р – сам объект, так и ссылка на объект. Четко указываем, что должны вызвать метод F из класса Х (Х должен совпадать с Р, либо быть базовым).

  • Такая же возможность есть и в Обероне: Draw^ (может появиться только внутри функции динамически связанной с типом, выведенного из типа Т)- вызов Draw для соответствующего базового класса.

Ада 95:

Замечание:

До этого момента мы рассматривали одну технику реализации ДС. Процедуры динамически привязаны к типу; виртуальные методы – это методы, которые вызываются динамически в зависимости от динамического типа соответствующей ссылки или указателя. Всегда речь идет об одном объекте – и виртуальные методы в Си++, и процедуры динамически привязанные в Си# - они все привязаны к одному объекту (это монометоды, которые всегда определяются динамическим типом одного объекта). Этот объект, например, мы и выделяем процедурой Draw().

PROCEDURE (VAR X:T) Draw(); // Х тут есть старый добрый this или self.

Рассмотрим, как реализовано динамическое связывание в Ада95 (никаких this или self нет):

В Аде: СWT(ClanWideType) – классовые типы, Т – тегированная запись. Именно из тегированных записей выводятся унаследуемые типы. При этом любой унаследованный тип по умолчанию является тегированной записью.

T - typed record

...

end record;

Type T1 is new T

with record ... //новые поля или ключевое слово no record – все это указывает, что наследование в ОО

смысле

end record

Классовый тип для такого Т: T ' class

Вспомним концепцию неограниченных типов данных, неограниченные тд в Ада они могут содержат потенциально бесконечное количество членов (пример: неограниченный массив с неограниченным диапазоном). T ' class – тоже является неограниченным типом, а именно множество значений типа T ' class - все объекты типа Т + все производные. Потенциально такое множество не ограниченное - в любой момент мы можем добавить новые производные объекты.

PROCEDURE P(A:T) is // Т – тегированная запись

begin

f(A);

end P;

  1. Пусть у нас есть типы Т (базовый) и Т1 (производный от него) и пусть у нас есть некоторая процедура F:

PROCEDURE F(X:T);

И ещё один её вариант (имеем право):

PROCEDURE F(X:T1);

  • Статическое перекрытие методов (компилятор знает тип и вызывает нужную функцию):

Y:T;

Y1:T1;

F(Y); //имеем право

F(Y1); // имеем право вызывать

  • Рассмотрим другой вызов:

P(Y); // f() for T

P(Y1); // f() for T – компилятор, когда генерирует код по вызову f(), он ничего не знает о том, как будет вызываться эта процедура Р. Даже если Т - тегированная запись, ничего особого не происходит.

2) Пусть теперь:

PROCEDURE P(A:T ' class) is //это меняет ситуацию

begin

f(A); //будет вызываться в зависимости от конкретного динамического типа А

end P;

Характеристики

Тип файла
Документ
Размер
115,5 Kb
Тип материала
Высшее учебное заведение

Тип файла документ

Документы такого типа открываются такими программами, как Microsoft Office Word на компьютерах Windows, Apple Pages на компьютерах Mac, Open Office - бесплатная альтернатива на различных платформах, в том числе Linux. Наиболее простым и современным решением будут Google документы, так как открываются онлайн без скачивания прямо в браузере на любой платформе. Существуют российские качественные аналоги, например от Яндекса.

Будьте внимательны на мобильных устройствах, так как там используются упрощённый функционал даже в официальном приложении от Microsoft, поэтому для просмотра скачивайте PDF-версию. А если нужно редактировать файл, то используйте оригинальный файл.

Файлы такого типа обычно разбиты на страницы, а текст может быть форматированным (жирный, курсив, выбор шрифта, таблицы и т.п.), а также в него можно добавлять изображения. Формат идеально подходит для рефератов, докладов и РПЗ курсовых проектов, которые необходимо распечатать. Кстати перед печатью также сохраняйте файл в PDF, так как принтер может начудить со шрифтами.

Список файлов лекций

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