ТОП 10:

Экспорт и импорт объектов. Инкапсулированные ЛТД.



Инкапсуляция – отделение абстрактного типа от реализации, с сокрытием её подробностей.

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

{т.е., когда мы вызываем функцию printf, нам не важно, на какой ОС мы работаем}.

Модуль – программная единица, изолированная от объектов других программ, что предохраняет её внутрнности от нежелательного доступа.

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

Типизация языка программирования. Контроль типов.

Типизация языка программирования – это наделения языка той или иной системой типо. .

Существуют бестиповые языки (Lisp), т.е. те, в которых все объекты одного и того же типа.

Строгая типизация – это статическая фиксация во время компиляции типа каждой переменной, массива, и т.д. .

Деятельность по определению типов переменных, функций и т.п. в программе называют контролем типов (во время компиляции – статический (Си); во время выполнения - динамический).

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

53 Средства ослабления типового контроля в языке Паскаль. Преобразование и передача типов.

Из практических соображений большинство языков программирования разрешает одновременное использовании данных нескольких типов (например, в одном выражении или разных частях оператора присваивания: было бы неудобно, если бы при записи значения в переменную типа double ВСЕХ участников выражения пришлось бы явно приводить к типу double от типа float, int, longint и т.д; неудобна и невозможность сравнить с помощью < целое число с машинно-рациональным).

Однако для этого требуется механизм согласования типов. Если он отсутствует, то происходит передача типа: внутреннее представление объекта одного типа предаётся функции интерпретации другого типа. Иногда это удобно: к примеру, для записи в файл данных без преобразования значений в изображение (== участка памяти как последовательности байт): в Си для этого достаточно преобразовать указатель на переменную некоторого типа к типу char*, после чего записать байты в файл. В случае родственности (например, математической: целые \sub рациональные \sub действительные) типов может иметь смысл функция преобразования всех значений одного типа в допустимые значения другого и наоборот. При этом ясно, что преобразование может быть неточным (ex.: разномощные множества (биекция невозможна)), необратимым, требовать немалого времени (к примеру, линейного (схема Горнера)).

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

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


 

Полиморфизм операций, отношений и процедур. Родовые модули.

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

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

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

Другой полезный пример – функция сортировки, упорядочивающая любые массивы, для элементов которых определено отношение порядка <.

Существует возможность введения полиморфных процедур с параметрами-типами. В данном контексте хочется отметить обобщённое (generic) программирование, хорошо представленное в языке С++: для реализации полиморфных функций, зависящих от типа передаваемых аргументов, в С++ используется понятие шаблона функции.

В языке Си полиморфизм аргументов функций может быть реализован с помощью указателей.

Рассмотрим идею на примере функции стандартной библиотеки языка Си qsort(void * base, size_tnum, size_tsize, int (* comparator) (constvoid *, constvoid *)). Путём задания указателя на начало сортируемого массива, количества его элементов, размера каждого элемента в байтах и указания функции сравнения двух элементов, можно сортировать практически любые объекты.

Аналогично можно описать функцию void* bsearch(constvoid *key, constvoid *base, size_tnum, size_tsize, int (* comparator) (constvoid *, constvoid *)), осуществляющую двоичный поиск ключа *key в массиве num элементов размером size байт каждый, начинающемся в base. При этом для сравнения используется функция-параметр comparator.

Можно заметить, что это довольно общая идея: сплошной объект в памяти задаётся своей первой и последней ячейками (или аналогично – первой ячейкой и размером элемента в сравнении с размером ячейки).

Обменные сортировки

Алгоритм:

1) берём первый элемент.

2) сравниваем со следующим.

3) если следующий больше – наш оставляем на месте и берём следующий; ELSE меняем местами.

4) п.2, пока не дошли до конца (эффективнее держать номер начала отсортированной части).

5) п.1пока есть эементы.

Улучшение – сортировка Шеёкер = 2пузырька, направленные в разные стороны (один тащит наименьтшие к началу, а другой – наибольшие к концу).

Пример – труба, в которой находятся разные по плотности не смешиваемые жидкости: более лёгкие всплывут на поверхность, а более тяжёлые уйдут на дно.

Прост в программирование, но сложность O(n^2) + один не удачно расположенный элемент будет “просачиваться” на своё место со скоростью 1 позиция за проход.


emplate<class T>

void bubbleSort(T a[], long size) {

long i, j;

T x;

for( i=0; i < size; i++) { // i - номер прохода

for(j = size-1; j>i; j-- ) { // внутренний цикл прохода

if ( a[j-1] > a[j] ) {

x=a[j-1]; a[j-1]=a[j]; a[j]=x;

}

}

}

}



 

55-56 Адресный тип. Реализация полиморфизма с помощью адресного типа на языке Си.

Для обеспечения процессов разнотипной интерпретации памяти необходимо применение родовых типов. Родовые типы данных уже заложены в конструкцию универсальных ЭВМ, память которых представляет собой слова, предназначенные для хранения данных произвольных типов. Ослабляя ограничения строго типизированных языков, можно ввести родовой тип данных word, не предполагающий какого-либо особенного использования памяти, выделенной для его объектов. Для этого типа определены лишь операция присваивания и отношение равенства. Поскольку он внутримашинный, он непечатаемый и в нём нет констант, изображающих конкретные значения. Основное его применение – ослабление контроля типов при передаче параметров. Любой формальный параметр типа word считается совместимым с любым фактическим параметром, занимающим ровно одно слово в памяти ЭВМ.

Более универсальный способ ослабления типового контроля – применение родовых (бестиповых) указателей. В соответствии с описанным выше типом word их можно ввести как указатели на word, распространяя типовую свободу word на мир ссылок и указателей. В Си бестиповый указатель может быть объявлен как void*. Фактически тип родового указателя вводит в обиход языка адреса соответствующей ЭВМ, единообразно ссылающиеся на данные любых типов, размещённые в ячейках её памяти. Поэтому он называется адресным типом.

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

57 -58 Процедурный тип данных. Реализация полиморфизма с помощью процедурного типа на языке. Проц.Тип д. – ещё одно средство реализации родовых модулей. Этот тип позволяет трактовать процедуры и функции как значения, которые можно присваивать переменным или передавать в качестве параметров другим подпрограммам. Фактически, процед. Тип данных представляет собой целый класс типов, отдельные типы которого есть множества глобально определённых процедур с идентичной спецификацией, включая и тип результата для функций. Константами процедурных типов являются имена глобальных процедур. Переменные процед. Типа принимают значения из соответствующего спецификации заголовка множества процедур. Разумеется, её можно и вызвать.

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

Процедурный тип позволяет описывать более универсальные родовые модули с хранимыми процедурами, поскольку подстановка параметров процедурного типа (интегрируемой функции – в «функцию» интегрирования) существенно повышает параметризацию такого модуля.

В Си и С++ просто предусмотрены указатели на функции (с возможностью приведения их к обобщённому указателю void*).

59 Наследование. Определять новый тип, наследующий те и только те атрибуты исходного типа, которые желательны.

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

Гарантировать применимость сохраняемых операций исходного типа к объектам нового типа.

Основные понятия и неформальные аксиомы наследования:

—Отношение наследования между родителем и наследником

— Атрибуты наследования

— Накопление атрибутов у наследника по отношению к родителю

— Типы объектов и экземпляры (объектов) определенных типов

Наследник обладает всеми атрибутами родителей, обратное неверно.

Право участвовать в операциях определенного класса — это атрибут наследования!

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

Наличие наследников не влияет на атрибуты родителей. Атрибуты могут быть абстрактными (виртуальными), и тем самым требовать конкретизации.

Преимущества развитой наследуемости: 1) Гармония открытости и защиты. 2) Поддерживаемая технология развития программной системы 3) Поддерживаемый стиль мышления адекватен естественному развитию от простого к сложному, от общего — к частному, от единого корня — к разнообразию, развитое наследование обеспечивает расширяемость объектов, типов и операций с защитой авторского права и с гарантией сохранности старых программ.







Последнее изменение этой страницы: 2016-08-14; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 34.204.202.44 (0.009 с.)