лекции (2007), страница 9

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

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

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

Онлайн просмотр документа "лекции (2007)"

Текст 9 страницы из документа "лекции (2007)"

Сomplex operator * (Complex a &, Complex b &) {return Complex(a.Re * b.Re, a.Im * b.Im);}

Теперь выражения с комплексными числами можно будет записывать просто как "a + b * c" и т.п. Но что делать, если какое-либо из чисел a, b или c не является комплексным, а имеет тип, например, int? Перегружать необходимые операторы для всех комбинаций возможных типов? Ведь возможных комбинаций могут быть десятки. Гораздо разумнее использовать неявные преобразования типов, а значит, и конструкторы преобразования. Для рассматриваемого примера достаточно определить всего один конструктор преобразования (для полной гибкости их потребуется несколько), к тому же для большей универсальности можно использовать параметры по умолчанию:

Complex (int a = 0, int b = 0) {Re = a; Im = b;}

Теперь все операции над комплексными числами можно записывать в виде вроде "a + b * c".

Однако и конструкторов преобразования не всегда достаточно. Например, может потребоваться преобразование из типа Complex, скажем, обратно в тип float (). Тогда в классе Complex необходимо определить оператор преобразования:

operator float () {return Re;}

Теперь можно переводить Complex во float:

float a;

Complex b(1, 1);

a = b;

Однако с неявными преобразованиями следует быть осторожными. Например, если программист совершит ошибку и присвоит объекту своего типа значение какого-то другого типа, то он может и не получить сообщение об ошибке: если есть конструктор преобразования, то он сработает, и вместо старого объекта, который будет потерян, дальше пойдёт новый, чего программист не хотел. Поэтому в C++ введено ключевое слово "explicit" которое показывает, что explicit-конструктор не будет вызываться при неявных преобразованиях (только явно).

С деструкторами всё проще, чем с конструкторами (в С++ деструктор в классе X описывается как ~X() {...} ): при уничтожении объекта класса иногда может потребоваться, например, освободить динамическую память, или выполнить какое-либо дополнительное действие (например, уменьшить счётчик объектов этого класса). Тогда имеет смысл писать деструктор.

В C++ конструкторы и деструкторы выполняются:

1) для статических объектов: конструкторы - до начала выполнения программы, деструкторы - после её завершения;

2) для квазистатических объектов: конструкторы - при входе в блок, деструкторы - при выходе из него;

3) для динамических объектов: конструкторы - при вызове new, деструкторы - при вызове delete;

Это всё относится к языку C++. В остальных языках всё проще.

Например, в Java: запрещены неявные преобразования, поэтому нет конструкторов преобразования. Запрещено и перекрытие операций, поэтому нет и конструкторов копирования; копирование в Java - это просто побитовое копирование. Если необходимо глубокое копирование, то необходимо использовать метод clone (), перекрыв его.

Глава 6. Инкапсуляция. Абстрактные типы данных.

Абстрактный ТД = множество операций; абстрактный класс - это, вообще говоря, не то же самое, что АТД.

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

1) Единица защиты - под ней понимают либо весь тип данных (все объекты одного типа защищены одинаково), либо отдельный его экземпляр (возможны разные стратегии защиты для разных объектов одного типа)

2) Атом защиты - это либо, опять же, весь тип данных (как в языках Ada и Modula-2 - либо полностью открыт, либо полностью закрыт), либо отдельные его элементы-члены (как во всех основных объектно-ориентированных ЯП, а также в языке Oberon)

Сначала рассмотрим подход к инкапсуляции в модульных языках. В языке Modula-2 атомом защиты является весь ТД. Вот как это выглядит:

Открытый вариант:

DEFINITION MODULE M;

TYPE T = ...;

...

END M;

Закрытый вариант (cкрытый тип данных в Modula-2 называется "opaque"):

DEFINITION MODULE M;

TYPE T;

...

END M;

IMPLEMENTATION MODULE M;

TYPE T = ...;

...

END M;

То есть в случае, когда тип открыт, скрытой остаётся только реализация операций, а структура ТД остаётся открытой; если же ТД является скрытым, то о нём известно только его имя. В связи с этим возникает проблема выделения памяти под скрытые типы данных. Поэтому на скрытые типы данных в Modula-2 накладывается дополнительное ограничение: они должны либо выглядеть, как указатели, либо быть совместимы с указателями по памяти (как, например, целый тип данных INTEGER). Кроме того, при такой реализации к скрытым ТД могут применимы не только операции, описанные в модуле определений, но и операции, обычно производимые над указателями: присваивание (поверхностное) и сравнение "равно - не равно".

В Ada атомом защиты тоже является ТД, но проблема выделения памяти под скрытые типы данных решена более изящно: структура данных описывается в специальной private-части определения, использовать которую может только компилятор. При этом ТД помечается ключевым словом "private" (приватный тип) или "limited private" (ограниченный приватный тип). Различие между ними в том, что к типам, помеченным как limited private, применимы только операции, определённые в описании, а к private-типам помимо них применимы ещё и операции присваивания и сравнения. Таким образом, только ограниченные приватные типы абсолютно точно воплощают концепцию абстрактных типов данных, так как именно в них разрешены только явно описанные операции.

Вот так, например, может выглядеть определение и реализация стека на языке Ada:

package Stacks is

...

type Stack is limited private;

procedure Pop (S : in out Stack ; X : out T);

procedure Push (S : in out Stack ; X : in T);

...

private

type Stack is access;

type Link is record

x : T;

next : Stack;

end record;

type Stack is access Link;

end Stacks;

package body Stacks is

...

procedure Pop (S : in out Stack ; X : out T) is ...

procedure Push (S : in out Stack ; X : in T) is ...

...

private

N: const Integer := 128;

type Stack is record

st_body : array (1..N) of T;

top : Integer := 1;

end record;

end Stacks;

В языке Oberon, в отличие от Modula-2 и Ada, атомом защиты является не весь тип данных, а его элементы. При этом те элементы, которые необходимо открыть, помечаются с помощью "*" и "*-" ("*-" означает, что элемент доступен только на чтение). Вот как выглядит определение всё того же стека в Oberon:

MODULE Stacks

TYPE Stack* = RECORD

Body : ARRAY 128 OF T;

Top : INTEGER;

Visible_element* : INTEGER;

END Stack;

...

END Stacks

...

IMPORT Stacks;

ST : M.T;

Таким образом, в Oberon АТД реализуется достаточно просто - необходимо закрыть доступ ко всем членам-данным и оставить открытым набор операций.

В языках с классами принято говорить не о видимости, а о правах доступа: структура всего класса видна, а вот использовать можно только те члены класса, к которым есть доступ. В C++ для управления доступом используются модификаторы "public", "private" и "protected". Соответственно, к public-членам доступ есть везде, к private-членам доступ возможен только внутри класса, а к protected-членам доступ возможен внутри класса и унаследованных от него классов. Эта схема очень проста, но не всегда удобна. Например, можно рассмотреть ситуацию, когда есть класс Complex и необходимо определить операцию сложения двух комплексных чисел a и b. Для этой операции необходимо иметь доступ к целой и вещественной части комплексных чисел, а значит, необходимо либо отказываться от инкапсуляции этих членов, что не есть хорошо, либо реализовать эту операцию "несимметрично", как a.operator+(b). Но при таком подходе не получится реализовать сложение без побочного эффекта, не меняющее оба своих операнда, а возвращающее третье значение.

Для преодоления этой проблемы в C++ реализован механизм дружественности ("friend"). Друзья класса - это функции или другие классы, которые описаны либо глобально, либо в других классах. Друзья имеют полный доступ ко всем членам класса:

class Complex

{

...

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

friend void Other_class_1 :: f ();

friend Other_class_2;

...

}

Необходимо заметить, что отношение дружественности не является транзитивным, то есть если класс Y - друг класса X, а класс Z - друг класса Y, то класс Z не становится другом класса X.

Примерно такая же схема инкапсуляции, только усовершенствованная, используется и в C#, и в Java, и в Delphi. Недостатком системы инкапсуляции в C++ была некоторая разрозненность файловой системы: код программы группируется только по классам и файлам. В современных объектно-ориентированных ЯП широко используется такое понятие, как проект; это некоторая совокупность логически близких файлов. На языковом уровне такое межфайловое объединение реализовано с помощью таких понятий, как пространство имён в C# ("namespace"), пакет в Java ("package") и модуль в Delphi ("unit"). Разумеется, во всех этих языках присутствуют атрибуты public, private и protected, с небольшими отличиями в свойствах.

Глава 7. Раздельная трансляция.

Различают несколько видов трансляции:

1) Пошаговая трансляция - программа подаётся компилятору небольшими частями, и он последовательно ("пошагово") эти части транслирует. Пример - транслятор языка Basic, где на каждом шаге обрабатывается один оператор языка. Пошаговая трансляция применяется только в языках с простой структурой, так как она крайне неэффективна. Самый простой пример - обработка циклов; цикл будет транслироваться столько раз, сколько в нём итераций:

LET I = 1

...

PRINT I

...

FOR I = 1 TO N

...

NEXT I

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

3) Цельная трансляция - компилятор сразу получает для трансляции всю программу. Очевидно, что такой подход неприменим для промышленного программирования, а может использоваться только для небольших программ. Цельная трансляция реализована, например, в языке Pascal.

4) Раздельная трансляция - программа разбивается на физически независимые части-модули (которые принято называть "единицами компиляции", ЕК), и эти части предъявляются компилятору. Раздельная трансляция разделяется на раздельную независимую трансляцию и раздельную зависимую трансляцию.

При независимой трансляции компилятору единовременно доступна только одна единица компиляции; соответственно, при зависимой трансляции помимо обрабатываемого модуля компилятору доступна информация о других модулях. Тем не менее, в обоих случаях для единицы компиляции возникает такое понятие, как "контекст трансляции" (КТ) - это совокупность имён (возможно, с какой-то дополнительной информацией о них), которые необходимы для трансляции этой единицы компиляции. Различие состоит в том, что при независимой трансляции программист должен сам налаживать межмодульные связи с помощью языковых средств (например, "extern" в C++), а при зависимой трансляции компилятор сам создаёт, хранит и обновляет соответствующие КТ. Контексты трансляции хранятся в так называемой трансляционной библиотеке (ТБ), а сами модули - в программной библиотеке (ПБ). Таким образом, при независимой трансляции компилятор обрабатывает только ЕК (в которые программист добавляет КТ), а при зависимой трансляции компилятор взаимодействует и с ЕК, и со всей трансляционной библиотекой, обновляя программную библиотеку.

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