Лекция 19 (1160817), страница 2

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

Текст из файла (страница 2)

px



f X::f

g X::g

Пусть есть класс Y, выведенный из Х, в котором мы переопределяем функцию f, и класс Z, выведенный из Y, в котором мы переопределяем функцию g. Значит Y наследует g от Х, а класс Z наследует f от Y. В классе Y также определяется виртуальная функция h, которая переопределяется в Z. ТВМ для Y

f Y::f

g X::g

h Y::h

Т.к. класс Y наследуется от Х, то начало ТВМ для Y будет таким же как и для Х, только f переопределяется. ТВМ для класса Z


f Y::f

g Z::g

h Z::h

Вызов. У нас есть указатель

px->f( );

В каждом объекте класса Х имеется указатель на таблицу виртуальных имен. Считая от начала класса ссылка на ТВМ всегда имеет фиксированное смещение для всех объектов. Поэтому компилятор знает, что под фиксированным смещением стоит ссылка на ТВМ, и какой вид имеет ТВМ для класса Х: по нулевому смещению в ней стоит адрес f. Задача компилятора косвенно добраться до таблицы виртуальных имен, взять из нулевого смещения адрес f и косвенным образом вызвать f. Понятно, откуда берутся накладные расходы: мы должны по этому указателю получить адрес соответствующей функции и сделать косвенный вызов. Что особенно приятно, эти накладные расходы фиксированы для любого типа данных, в отличии от языка Smalltalk. Если во всех языках, которые мы рассматриваем, мы объявляем динамику связывания метода при трансляции, равно как и его сигнатуру, то в языке Smalltalk таблица методов может пополняться динамически. Память в языке Smalltalk распределяется не линейным образом, а цепным. Если у нас есть некоторая иерархия

O bject

Х

Y

Z

Если ссылка указывает на объект класса Z и есть вызов какого-то объекта, то поиск метода производится следующим образом: динамически в таблице проверяется существует реализация такого метода или нет. Если не существует мы идем на суперкласс Y, если нет в таблице методов для этого класса, то идем на класс Х и т.д. до тех пор, пока мы не дойдем до типа данных Object, который является вершиной соответствующей иерархии. Если и в Object нет реализации этого метода, тогда динамически выдается сообщение об ошибке. Т.е. компилятор языка Smalltalk в принципе не может проверить есть такой метод или нет, поскольку речь идет о чистой динамике. Чем длинней иерархия классов, тем больше может занять поиск соответствующего метода. С практической точки зрения подобного рода реализация является очень гибкой. Но для реальных промышленных приложений, где требуется эффективность, такой метод реализации не является приемлемым. В С++ и всех языках, которые на нем основаны, есть небольшие накладные расходы (порядка 6 – 9 ассемблерных команд), но они во многих случаях являются вполне приемлемыми. Они никак не зависят от глубины иерархии.

ТВМ создается одна для всех экземпляров класса. Вроде бы это не большие расходы по памяти – заводить для каждого типа данных свою ТВМ, но в некоторых случаях такой расход является слишком накладным. Рассмотрим типичный пример: система графического интерфейса пользователя. Типичная для этого случая иерархия классов

CWindow

CMenu CFrameWind CDlgWindow CViewWindow

CFrameWind - главное окно. Типичное приложение – это Frame Window, внутри которого всавлено View Window и иногда может возникать Dialog Window и т.д. – по одному экземпляру каждого класса. Все нормальные системы интерфейса пользователя являются событийно-ориентированными. Для каждого вида событий должна быть задана в базовом классе функция – обработчик этого события. В базовой версии Windows было 144 события. Если реализовывать такой механизм обработки событий с классической объектно-ориентированной точки зрения, то каждая таблица виртуальных методов должна иметь по меньшей мере 144 метода (реакции на данные события). 144 метода для каждого типа окон и для базового типа. Причем у нас всего по одному экземпляру каждого, и с каждым экземпляром, в результате, у нас связана своя ТВМ. Т.е. накладные расходы по памяти на ТВМ становятся больше, чем на объекты самого класса. Это пример не реальной иерархии. Реальные иерархии классов, например, в MFC, значительно длиннее, и как правило заводится по одному - два объекта для каждого класса такой иерархии. Накладные расходы на ТВМ становятся слишком большими. Поэтому, как правило, событийно-ориентированные интерфейсы с огромным количеством событий, где каждый объект в иерархии должен реагировать на каждое возможное событие, реализуются с помощью механизма динамической диспетчеризации, когда заводится некоторая табличка (она как правило является хеш-таблицей), в которую включаются только те указатели, которые реально есть. Если CWindow умеет отвечать только на 10 из этих событий, а остальные просто игнорирует, то в соответствующей таблице будет 10 указателей. В свое время фирма Borland стала расширять реализацию языка С++, чтобы допускать подобного рода вещи. И в языке Delphi, и в языке Borland C++ появились динамические методы, которые были реализованы через динамическую диспетчеризацию. А фирма Microsoft пошла по другому пути: она стала создавать так называемые таблицы сообщений с помощью макросов, оставаясь в рамках стандартной реализации языка С++. Достаточно много менеджеров программных проектов не захотели принимать идеологию Borland потому, что Borland специфическим образом расширял язык С++.

Оберон.

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

TYPE T = RECORD

END

Обычная процедура выглядит так

PROCEDURE P(VAR X:T);

Никакой динамической привязки здесь нет.

PROCEDURE (VAR X:T) P( );

Это означает, что процедуру Р можно переопределять, если ее динамическим параметром будет производный от Т класс.

TYPE T1 = RECORD(T)

END

Для класса Т1 мы имеем право написать свою реализацию процедуры Р

PROCEDURE (VAR X:T1) P( );

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

PROCEDURE F(VAR X: T);

В процедуре F есть вызов

X.P( );

Вызов очень похож на вызов методов из ООП.

VAR A: T;

B:T1;

Компилятор, когда транслирует функцию F, не знает какого реально динамического типа будет Х (Х передается по ссылке). При вызове F(A) будет вызываться Р для типа Т, при вызове F(B) будет вызываться Р для типа Т1 => это зависит от того каким будет фактический параметр. Не зная фактического параметра, оттранслировать вызов не можем, компилятор вставляет соответствующий динамический вызов. Даже по синтаксису они очень напоминают виртуальные методы в языках С++, C#, Java, Delphi.

Динамическое связывание методов в языке Ада 95.

Необходимо было, чтобы новая система типов, т.е. объектно-ориентированное расширение языка, включалась бы в язык мягким образом. Т.е. программы на языке Ада 83 одновременно должны быть программами на языке Ада 95. Это достаточно сложная задача, и создатели Ада 95 решили ее достаточно адекватно.

tagged record …end

Такие записи можно расширять.

type T1 is new T with record … end;

Т обязан быть помеченной записью или наследником помеченной записи. Без динамического связывания с тем же успехом можно было бы говорить об отношении включения. В языке Ада введено понятие class-wide types (cw-типы или типы класса). Если Т – расширяемый класс (т.е. либо это помеченная запись, либо запись, унаследованная от помеченной), то тогда вводится понятие

T'class

class – новое ключевое слово (программы на языке Ада 83, которые использовали одноименные идентификаторы стали непроходимыми, нужно один раз перекомпилировать). Это чем-то похоже на понятие неограниченных типов в Аде (например, массив, у которого не фиксировался диапазон). Переменные таких типов имели смысл только как формальные параметры процедур. Объектами этого типа могут являться переменные типа Т + переменные всех типов, которые могут быть выведены из Т.

X:T'class;

Х – переменная, которой можно присваивать любой объект типа Т + любой объект типа производного от Т. С точки зрения реализации Х выступает как ссылка на объект типа Т. Если у нас есть какая-то иерархия

Т => T1 => T2

A: T; B: T1; C: T2;

Можно производить присваивания

X:= A; X:= B; X:= C;

Ссылки могут иметь динамический тип. Представим, что у нас есть пакет М, в котором определяется тип данных Т и

procedure P(X: T);

Пусть в пакете М1 из типа Т выводится тип Т1 и переопределяется процедура

procedure P(X: T1);

(это можно было делать и в Ада 83). Пусть в пакете М2 из типа данных Т1 выводится тип данных Т2 и переопределяется процедура

procedure P(X: T2);

В других языках (в Обероне, в C#, в Delphi) специально помечаются методы, которые могут быть динамическими. Рассмотрим

PROCEDURE F1(X: in out T);

PROCEDURE F2(X: T'class);

В процедурах F1 и F2 вызывается процедура

P(X);

Это все вполне допустимо. В случае вызова P(X) в процедуре F1 никакой динамической привязки. Для всех случаев

F1(A); F1(B); F1(C);

поскольку речь идет о типе данных Т, то будет вызываться процедура Р для Т (т.е. Р из модуля М) потому, что компилятор в этом месте просто вставит статическую привязку. Для F2 ситуация другая.

F2(A); F2(B); F2(C);

Здесь будет вызываться Р(Х) в зависимости от динамического типа. В случае F2(А) будет вызвана процедура Р для типа Т, в случае F2(B) – процедура Р для типа Т1, в случае F2(C) – процедура Р для типа Т2. Вызов Р(х) в F2 будет динамически привязан. Т.е. одну и ту же процедуру можно вызывать как статически привязанной, так и динамически привязанной – все зависит от параметра.

Это выглядит очень похоже. На самом деле такой механизм привязки оказывается несколько богаче, чем может показаться на первый взгляд. Для всех методов, которые мы писали для С++ и прочих языков, аналогичные вещи можно сделать и для языка Ада. Но язык Ада (Ада 95) позволяет еще некоторое расширение, которое не позволяют все те языки, о которых мы говорили. Это так называемые мультиметоды. Фактически мультиметоды реализованы как понятие только в языке Ада 95. В С++ Страуструп в своей книге обсуждал потребность в мультиметодах, но тем не менее мультиметоды в языке С++ не реализованы. Слово мультиметоды не имеет никакого отношения к множественному наследованию. Мультиметод – это динамически связанный метод, который вызывается в зависимости от динамического типа нескольких объектов. До этого динамическая привязка всегда шла по одному типу объекта. В классовых языках метод класса вызывается в зависимости от динамического типа соответствующего объекта х

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

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

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

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