лекции (2004) (1160823), страница 12

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

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

В) Интересная ситуация с языком Cи#, который с одной стороны претендует на роль чистого объектно-ориентированного языка (J# - расширение языка Java под .NET, и если сравнивать J# и Cи#, то Cи# гораздо ближе к Java, чем к Си++). Cи# гораздо шире по своим возможностям, не за счет новых концепций, а потому что расширена область применения языка. Так в Cи# есть указатели, но они могут применяться только в специальных блоках. В есть unsafe-блоки, в которых мы можем делать небезопасный код, очень похожий на Си++. Такие блоки должны быть подписаны, и пользователь может отключить их. Так, например:

Unsafe

{

char *m = malloc (10);

}

Понятие функционального типа данных оказалось достаточно удобным, появилась специальная концепция делегатов - обладает концепциями функционального типа. Обладает многими достоинствами функционального тд, в то же время не обладая его недостатками. Введено понятие делегата, внешне объявление делегата очень похоже на объявление функционального типа и в Обероне, и в Модуле 2, и в Аде 95. Ключевое слово delegate, за которым идёт спецификация подпрограммы.

delegate void Handler (Object o, Args e); // Handler - имя функционального типа.

В Cи#, как и в языке Java, нет просто функций. Есть понятие пространства имен, внутри этого пространства могут быть только объявления классов и перечислимых типов. Нет понятий глобальных функций или глобальных переменных. Если речь идет о функции, то сразу определяется к какому классу она принадлежит.

  • Если есть объявление Handler P; то P - делегат (функция с двумя указанными выше параметрами Object o, Args e). Вызывать её можно как обычно:

string S;

Args t;

P(S, t); // поскольку любой объект может быть преобразован к класс object, то это здесь и произойдет с помощью специальной процедуры boxing

  • К делегату применимы операции:

- круглые скобки (вызов функции)

- присваивание (P = F), внешне делегат выглядит как функция;

void F(Object o, Args x);

void G(Object o, Args x);

P = F; // такое присваивание инициализирует делегат, если попытаемся вызвать неинициализированный делегат, то произойдет системная ошибка

- "+=" и "-=": P+=G - делегат может иметь в себе несколько объектов функционального типа. P-=F; (добавление и исключение функций из списка). Вызов делегата в таком случае – это поочередной вызов зарегистрированных функций. Порядок вызова не фиксирован.

Чем делегат удобней, чем указатели на члены:

1. Делегат может держать несколько функций.

2. Делегат - конструкция безопасная. Никакого отношения к понятию указателя делегат не имеет.

3. обговаривалось, что в Си# все функции являются функциями-членами, однако при P=F, ничего не говорилось о том, что собой представляет функция F. Присваивание P=F не совсем верно. Надо сначала инициализировать:

P = new Handler(F); // (только для статических функций-членов класса)

P = new Handler (X.F); // Где: X - ссылка на целевой объект (target object); F - имя соответствующей функции;

А в делегатском списке каждый элемент – это ссылка на целевой объект и ссылки на соответствующую функцию. Таким образом делегаты похожи на указатели на члены из Си++, но все-таки делегаты шире. Потому что указатель на член – может быть только указателем на член данного класса, а здесь объектами одного и того же делегата могут быть любые функции, удовлетворяющие прототипу соответствующего хедера. А в случае указателей – указатель на статический объект будет нулевым, и компилятор это определит. Имя_объекта.имя_функции – это ссылка на объект запоминается как целевой объект, и соответственно ссылка на метод, компилятор проверит совпадает ли метод с сигнатурой делегата.

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

Частным случаем делегатов являются события, о которых мы будем говорить позже.

Переменный список аргументов.

Уже в языке С++ появился переменный список аргументов, например:

int printf(const char* fmt, ...); // Функция обязана иметь хотя бы один явный аргумент.

Для использования списка параметров дополнительно были введены специальные макросы: va_start, va_list, va_end, которые позволяют получить доступ поочередно к каждому параметру из списка, этот параметр считается совместим с int или с любым указательным типом, например void *. Берем и преобразуем к нужному типу, при этом никакого контроля нет, эта возможность признавалась одной из самых опасных в Си и Си++. Раз она опасна, то ее следует изничтожить.

В Паскале так же были переменные списки параметров, но только в стандартных процедурах. Например, writeln (x,y,z); // верно

writeln; // верно

Именно с точки зрения ввода-вывода переменный список параметров очень удобен.

Пример: на Си

printf("Count = %d\n", cnt);

на языке Оберон то же самое:

InOut.WriteString("Count = ");

InOut.WriteInt(cnt)

InOut.Writeln;

И это только для одного параметра, а если их будет больше? Кроме того проблема читабельности текста программы.

Концепция объектной ориентации может довольно элегантно решить эту проблему. Так в Си# ее решили достаточно просто. Напомним, что любой класс языка наследуется из класса Object, а любого не-класса (структура, или объект простого тд) существуют классы обертки.

Console.Write("Count = {0}\n", Cnt);// это метод имеет переменное число параметров

Процедура write имеет прототип:

void Write(String fmt, params object[] args); {0} - индекс элемента в списке параметров, индексы в общем случае могут быть вычисляемы

params – ключевое слово, когда компилятор видит это слово, первый параметр отождествляет с форматом, а из переменного списка параметров делает массив. У массива есть свойство длина – сразу можно вычислить. Как write догадывается, что нужно выводить целое число – по типу. В современных объектно-ориентированных языках есть динамическая идентификация типа, у нас есть надежное и контролируемое преобразование из ссылки object к любому конкретному типу Т. Могут быть ошибки, но эти ошибки будут отловлены именно в момент их возникновения, у нас не произойдет соответствующего преобразования типов.

Общий вид:

params T[] args - соответствует любой список параметров от пустого. Компилятор пытается переменный список объектов свести к однотипным объектам, тем которые указаны в объявлении, а ключевое слово params говорит о том, что отождествляется произвольный список, если его убрать то void Write(String fmt, Т[] args); - всего два параметра, второй – это массив (уже не компилятор, а сам программист его формирует). Такое решение может привести к дополнительным накладным расходам, но является надежным.

Глава 4: Определение новых типов данных

Определение: Тип данных - это множество значений (определяется самой структурой типа) плюс множество операций (определяет поведение объекта данного типа). Тип данных характеризуется прежде всего множеством операций.

Пример1: множество значений не есть однозначное множество

А)Типы int и unsigned int в языках Си и Си++ одинаковое множество значений, по крайней мере, с точки зрения реализации, но разное множество операций.

Б)В Си# byte: 0-255, sbyte: -128-127 - с точки зрения реализации множество значений одинакова, но разная интерпретация этого множества значений, а именно с точки зрения множества операций и семантики операций типы и отличаются.

Пример 2:

record

body: array [1..50] of T;

t: integer;

end.

Что это за тип – может быть что угодно, однако мы можем сказать, что это стек (где Т – верхушка, body – тело – хотя этого можно и не говорить), и применимы операции:

Push(X: T);

T Pop();

IsEmpty();

И сказать, что если применить push, а затем сразу pop то вернется Х. Теперь понятно какой тип данных мы ввели.

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

Все ЯП делятся на две основные группы:

1. Модульные языки (Модула-2, Оберон, Дельфи, Ада) - существует концепция Module, Unit, Package - логический модуль, который представляет собой коллекция ресурсов;

2. ЯП с классами - есть понятие класс, с одной стороны является обёрткой (сводит множество значений и множество операций), но ещё он является и типом (дуальность классов).

Понятие объектной ориентированности не сводится к понятию класса (обертка и тип одновременно), например, Ада 95 - модульный язык, но нет отдельного понятия класса (как обёртки), хотя есть ключевое слово class.

Модульные языки.

п.1. Понятие логического модуля

Трудно дать определение модуля, никакой четкой синтаксической структуры у модуля в разных яп нет. Модуль – это средство группировки, у модуля есть начало – заголовок, конец и внутреннее содержание. Только с точки зрения синтаксической структуры на модуль смотреть нельзя. Пример: рассмотрим условный оператор во многих яп,

if E then

S1

Else

S2

Endif

Тут тоже есть начало, конец и некоторое содержание, но модулем отдельные операторы никто не называет. Вот процедуру еще можно назвать модулем, пакет языка Ада точно можно назвать модулем.

Логический модуль (ЛМ) – то, что проще заимствовать, чем разрабатывать заново (неформальное определение из книги Кауфмана). С этой точки зрения при заимствовании операторов из кола мы их все-таки меняем («метод copy-paste» не рассматривается ), заимствование процедур, а особенно модулей, классов – распространено. Такие заимствования обычно не изменяются.

Итак модуль:

  1. средство группировки ресурсов

  2. механизм заимствования - для модуля всегда возникает понятие экспорта и импорта

При рассмотрении модуля как средства группировки – слово «логический» означает, то что мы абстрагируемся от разделения программы на физические модули. Физический модуль (ФМ) - понятие отличное от логического модуля. В Java ФМ - файл, ЛМ - класс и пакет. В Дельфи - ФМ и ЛМ совпадают, каждый unit находится в отдельном файле, и каждый фаил не может содержать больше одного unit’а. О взаимосвязях между логическими и физическими модулями будем еще говорит в главе посвященной раздельной компиляции. Сейчас речь пойдет только о ЛМ.

Рассмотрим простейший случай ЛМ, реализованный в Модуле-2 (похожее в Дельфи и Обероне).

1. Модули в Модуле-2 - очень важные понятия. Есть один главный модуль, и есть библиотечные модули (модули определений и модули реализаций). В модули определений содержатся только объявления структур данных и объявление операций, в модули реализаций - тела методов, вспомогательные процедуры, которые нужны только для реализации основных.

  • Главный модуль:

MODULE name;

.... объявления

BEGIN

операторы

END name.

  • Модули определения:

DEFINITION MODULE имя;

Только объявления

END имя.

  • Модуль реализации:

IMPLEMENTATION MODULE имя;

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

Пример:

Модуль определений

DEFINITION MODULE Stacks;

CONST N = 50;

TYPE Stack = RECORD

body: ARRAY [1..N] OF Integer;

top: Integer;

END;

PROCEDURE Push (VARS: Stack; X:INTEGER);

PROCEDURE Pop (VAR S: Stack):Integer;

PROCEDURE Init (VAR S: Stack); // на что будет тор указывать

.............

VAR Done: Boolean; // true, если последняя операция успешна, false иначе

END Stacks;

Модуль реализаций

IMPLEMENTATION MODULE Stacks;

...

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

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

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

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