Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Коллоквиум 2012.doc
Скачиваний:
23
Добавлен:
25.08.2019
Размер:
346.11 Кб
Скачать

Эволюция методологий программирования. Парадигмы программирования.

III семестр

Основные тенденции:

  • Смещение акцентов от частного, к общему (от программирования деталей к программированию компонент);

  • Развитие и совершенствование инструментария программиста (языков программирования и рабочей среды);

  • Увеличение сложности программных и информационных систем.

Стиль программирования(Бобков, Стефик) - способ построения программ, основанный на определенных принципах программирования, и выбор языка, который делает понятными программы, написанные в этом стиле.

Основные стили :

  • Процедурно-ориентированный (алгоритмы);

  • Объектно-ориентированный (классы и объекты);

  • Логико-ориентированный (цели, предикаты);

  • Ориентированный на правила (если - то);

  • Ориентированный на ограничения (инвариант).

Инвариантом в программировании называется логическое выражение, истинное после каждого прохода тела цикла и перед началом выполнения цикла. Выражение зависит от переменных, изменяющихся в теле цикла.

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

Парадигмы:

  • Процедурное программирование - решите, какие требуются процедуры, используйте наилучшие доступные алгоритмы;

  • Модульное программирование - решите, какие требуются модули, разбейте программу так, чтобы скрыть данные в модулях;

  • Объектное программирование - решить, какие требуются типы, обеспечьте полный набор операций для каждого типа;

Определения ОО языки:

  • программа, написанная на объектном языке, представляет собой совокупность объектов, каждый из которых принадлежит к определенному классу. Каждый объект имеет интерфейс в виде методов для взаимодействия друг с другим объектом посредством посылки сообщений (вызова методов);

  • в объектно-ориентированном языке, в отличие от объектного, классы образуют иерархии наследования, что позволяет воспользоваться преимуществами полиморфизма и динамического поведения типов.

Парадигма ООП:

  • Решите какие требуются классы, обеспечьте полный набор операций для каждого класса, выразите общность через наследование (абстракция, инкапсуляция, иерархия);

  • Разбейте систему на сильно связанные внутри и слабо связанные между собой модули, сгруппируейте абстракции по модулям;

  • Используйте наилучшие алгоритмы для реализации методов классов.

Типы данных С++:

  • Фундаментальные типы:

    • интегральные (bool, char, wchar_t, short, int, long)

    • с плавающей точкой (float, double, long double)

    • void

  • Перечислимые типы (enum)

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

    • struct, class, union

  • Конструируемые типы:

    • указатели (Т*, Т** ...)

    • массивы (Т[], T[][] ...)

    • ссылки (T&)

Основные определения.

Объявление - объявляется только тип и имя сущности.

Определение - определяется реализация или размещение - определяется сущность.

lvalue - это выражение, ссылающиеся на объект.

rvalue - это выражение, которое имеет значение и может стоять справа от знака присваивания.

Ссылка - альтернативное имя объекта. Ее нельзя объявить, можно только определить.

Перегрузка - использование одного имени для операции, выполняемой разными типами.

Разрешение перегрузки:

  • точное разрешение типов, те полное соответствие или соответствие, достигаемое тривиальными преобразованиями типов;

  • соответствие, достигаемое продвижением интегральных типов;

  • соответствие, достигаемое путем стандартных преобразований;

  • соответствие, достигаемое путем преобразований, определяемых пользователем;

  • соответствие за счет “...”.

Объекты (по Бучу):

  • Объект обладает состоянием, поведением и идентичностью. Структура и поведение схожих объектов определяет общий для них класс;

  • Состояние объекта характеризуется перечнем всех свойств объекта и текущим значением каждого из этих свойств;

  • Поведение - действия и реакция объекта, выражаемые в терминах состояния объекта и передачи сообщений;

  • Идентичность - свойство объекта, отличающее его от всех других объектов.

Классификация методов объекта:

  • Конструктор - метод создания объекта и/или его инициализации;

  • Деструктор - метод уничтожения объекта и освобождения ресурсов, используемых объектом;

  • Селектор - метод, позволяющий получить информацию без изменения внутреннего состояния объекта;

  • Модификатор - метод, изменяющий состояние объекта;

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

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

Взаимоотношения между объектами:

  • Ассоциация (связь) - отношение, позволяющее реализовать взаимодействие клиент-сервер (объект-клиент вызывает метод у объекта-сервера);

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

Главные принципы ООП:

  • Абстрагирование;

  • Инкапсуляция;

  • Модульность;

  • Иерархия.

Дополнительные принципы ООП:

  • Типизация;

  • Параллелизм;

  • Сохраняемость.

Абстрагирование:

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

  • Шоу. Абстрагирование - упрощенное описание или изложение системы, при котором одни свойства и детали выделяются, а другие - опускаются. Хорошей является та абстракция, которая подчеркивает детали существенные для рассмотрения и использования, и опускает те, которые на данный момент не существенны.

  • Берзинс, Грей, Науман. Идея квалифицируется как абстракция, только если может быть изложена, понята и проанализирована независимо от механизма, которые будет в последствии использован для ее реализации.

  • Буч. Абстракция выделяет существенные характеристики некоторого объекта, отличающие его от других видов объектов и, таким образом, четко определяет его концептуальные границы с точки зрения наблюдателя.

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

Главная задача проектирования - выделение полного и достаточного набора абстракций.

Виды абстракций:

  • Абстракция сущности - объект представляет собой полезную модель сущности в предметной области;

  • Абстракция поведения - объект состоит из обобщенного множества абстракций;

  • Абстракция виртуальной машины - объект группирует операции, которые вместе используются более высоким уровнем управления, либо сами используют некоторый набор операций более низкого уровня.

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

Правило единственности абстракции. Класс должен обладать единственной ответственностью, реализуя ее полностью, реализуя ее хорошо и реализуя только ее.

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

Реализация описывает представление абстракции и механизмы достижения желаемого поведения объекта.

Модульность - свойство системы, которая была разложена на внутренне связные, но слабо связные между собой модули.

Принцип инверсии зависимостей. Модули высокого уровня не должны зависеть от модулей низкого. И те и другие должны зависеть от абстракций.

Иерархия - это упорядочивание абстракций путем расположения их по уровням.

Виды иерархических отношений:

  • Иерархии классов (отношение “is a”) - отношение вида родитель-потомок., реализуется при помощи наследования типов.

  • Иерархии объектов (отношение “part of”) - отношение вида часть-целое. Реализуется агрегацией и композицией.

Типизация - способ защититься от использования объектов одного класса вместо другого или по крайней мере управлять таким использованием.

Сильная типизация определяет одно или несколько ограничений относительно того, как операции, связанные со значениями различных типов данных, могут быть перемешаны. Язык программирования, который реализует строгую типизацию, будет препятствовать успешному выполнению операций на аргументах, которые имеют неправильный тип.

Слабая типизация означает, что язык неявно преобразует типы при использовании. К примеру, если мы будет складывать переменные типа char и int, то результат такой операции будет не определен.

Динамическая типизация - прием, при котором переменная связывается с типом в момент присваивания значения, а не в момент объявления переменной.

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

Статистическое связывание. Тип адресуемого объекта ровно как и тип результата выражения определен еще на стадии компиляции.

Динамическое связывание. Тип адресуемого объекта определяется во время исполнения.

С++ сильно типизированный язык с динамическим связыванием.

Виртуальный полиморфизм - союз типизации, наследования и динамического связывания.

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

Виды объектов:

  • Объекты-актеры - объекты, которые воздействуют на другие объекты, но сами не подвергаются воздействию;

  • Объекты-серверы - объекты, которые могут только подвергаться взаимодействию со стороны других объектов;

  • Объекты-агенты - объекты, которые выступают как в активной, так и в пассивной роли, являясь, таким образом, переносчиками взаимодействий в системе.

Видимость. Для того чтобы объект-клиент мог вызвать метод у объекта-сервера, сервер должен быть адресуем со стороны клиента:

  • Сервер имеет глобальную видимость по отношению к клиенту;

  • Сервер передан клиенту в качестве параметра при вызове метода, либо получен в качестве возвращаемого значения вызванного метода;

  • Сервер является частью клиента (агрегация);

  • Сервер локально порождается клиентом в ходе выполнения какого-либо метода.

Моделируемая система представляется в виде совокупности взаимодействующих между собой объектов во время исполнения программы в памяти ЭВМ. Объекты описываются в терминах классов на языке программирования и в системах моделирования.

Класс - множество объектов, имеющих общую структуру и поведение.

Мета-класс - класс, экземпляры которого являются классами.

Средства обобщенного программирования - шаблоны классов (родовые компоненты). Позволяют порождать родственные классы.

Инстанцирование объектов - создание объекта на основе класса.

Инстанцирование шаблонов - создание класса на основе шаблона класса.

Структура класса. Класс задается своим типом (именем класса), информацией о суперклассе и реализуемых интерфейсах, а также своими членами:

  • Полями и методами экземпляра (реализуют свойства объекта);

  • Статическими полями и методами класса (реализуют собственно свойства и поведение самого класса);

  • Внутренними абстракциями (вложенные и внутренние классы и интерфейсы, как правило, не используемые извне класса).

Классы и инкапсуляция:

  • Открытый (public) - члены с данным уровнем доступа видимы всем клиентам класса;

  • Защищенный (protected) - члены этого уровня видимы самому классу, его подклассам и абстракциям (классам и интерфейсам);

  • Закрытый (private) - члены данного уровня видны только изнутри самого класса.

Абстрактный класс - класс, содержащий объявленные, но не определенные методы. Экземпляры абстрактного класса не могут быть созданы, возможно объявить лишь ссылки (или указатели) имеющие своим типом абстрактный класс.

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

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

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

  • Ассоциация. Мощность ассоциации:

    • Один - к - одному;

    • Один - ко - многим;

    • Многие - ко - многим.

  • Агрегация. Композиция - агрегация, которая зависит от времени жизни объектов.

  • Наследование.

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

В определение класса могут быть включены:

  • объявление статических полей;

  • определения нестатических полей и констант;

  • объявление статических и нестатических функций-членов;;

  • определения статических и нестатических функций-членов;

  • объявление вложенных типов;

  • определения вложенных типов;

  • декларации дружественности;

  • декларации использования.

Назначение членов класса:

  • Нестатические поля определяют состояние объекта класса и доступны только в контексте объекта;

  • Статические поля разделяются всеми членами класса и, таким образом, являются переменными самого класса;

  • Нестатические функции определяют поведение объекта и доступны только в контексте объекта. Нестатические функции могут оперировать как статическими, так и не статическими полями класса;

  • Статические функции определяют поведение самого класса и не могут обращаться к нестатическим полям.

Типы памяти в С++:

  • Статическая (глобальные переменные, переменные пространств имен, статические члены классов и статические переменные функций). Выделением статической памяти занимается компоновщик;

  • Автоматическая (аргументы функций и локальные переменные, которые автоматически создаются и уничтожаются). Автоматической памятью управляет компилятор.

  • Свободная (динамическая). Свободной памятью управляет программист в коде программы с помощью new, delete, malloc, free.

Создание и уничтожение объектов:

  • именованный автоматический объект;

  • объект в свободной памяти (new, delete);

  • нестатический член-объект - композиция;

  • элемент массива, который создается и удаляется совместно с массивом;

  • локальный, статический объект в функции создается при первом прохождении потока исполнения;

  • глобальные объекты, члены пространств имен, статические члены классов;

  • временные объекты, создаваемые как часть вычисления выражения и удаляемые по завершении выражения;

  • placement new, placment delete.

Перегрузка операторов - средство для короткой записи предопределенного поведения.

Ограничения:

  • Оператор может быть объявлен только с синтаксисом, существующим для него в грамматике языка;

  • Операторы должны быть нестатическими функциями-членами, либо функциями - не членами с одним или двумя аргументами;

  • Нельзя определить операторы :: . .* ?;

  • Нельзя ввести новую лексему, например **;

  • Нельзя изменить смысл операторов языка new, delete, sizeof, typeid, xxx_cast;

  • operator=, operator[], operator-> должны быть нестатическими функциями-членами (левый аргумент - lvalue).

Модули С++:

  • С целью оптимизации процесса разработки и борьбы со сложностью системы абстракций программы на С++ разбиваются на модули (исходные файлы - единицы компиляции “.сс” “.срр”);

  • Каждый файл может содержать объявления и определения элементов программы (переменных, функций, структур и классов, шаблонов, определений типа typedef, пространств имен и т.д.);

  • Каждый элемент имеет свой тип связи(linkage):

    • no linkage (для элементов на стеке);

    • internal linkage (область видимости - файл);

    • external linkage (область видимости - проект).

Этапы трансляции и загрузки:

  • Компиляция:

    • Подготовка единиц компиляции (препроцессирование+синтаксический анализ);

    • Разрешение зависимостей внутри модуля(internal linkage);

    • Генерация кода объектного модуля (“.obj”, “.o”).

  • Компоновка (линовка):

    • Разрешение зависимостей между модулями;

    • Генерация исполняемого файла(“.exe”), архивной (.lib“) либо динамической библиотеки (“.ld.so”, “.dll”).

  • Запуск процесса:

    • Загрузка программы и инициализация данных;

    • Разрешение динамических связей (загрузка динамических библиотек).

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

Могут содержать:

  • Именованные пространства имен;

  • Определения типов;

  • Объявление шаблонов;

  • Определения шаблонов;

  • Объявление функций;

  • Определения inline функций;

  • Объявление данных;

  • Определения констант;

  • Перечисления;

  • Объявления имен;

  • Директивы включения;

  • Директивы условной компиляции;

  • Комментарии.

Не должны содержать:

  • Определения обычных функций;

  • Определения данных;

  • Определения агрегатов;

  • Неименованные пространства имен;

  • Экспортируемые определения шаблонов.

Правило одного определения (ODR). Два определения класса, шаблона или inline функции допустимы в качестве определения одной и той же сущности тогда и только тогда, когда:

  • Они расположены в разных единицах трансляции;

  • Они идентичны лексема за лексемой;

  • Значения лексем одинаковы в обоих единицах трансляции.

Инициализация нелокальных переменных:

  • Исполнение программы начинается с вызова функции main() и заканчивается с возвратом из этой функции;

  • Все нелокальные переменные инициализируются перед вызовом main;

  • Нет гарантированного порядка инициализации переменных, объявленных в разных единицах трансляции;

  • В одной единице трансляции инициализация идет в порядке объявления переменных.

Наследование - основной механизм ООП:

  • Уточнение (переопределение поведения - перегрузка);

  • Расширение интерфейса абстракции;

  • Переиспользование (использование ранее написанного кода).

Уточнение и расширение - базис, в направлениях которого идут изменения в классах.

LSP(Liskov substitution principle). Функция, принимающая в качестве аргумента объект базового класса должна уметь работать с объектами любых открытых производных классов.

Закрытое наследование. class D: private B{...}:

  • открытые и защищенные члены класса B могут использоваться только функциями-членами и друзьями класса D. Доступ к ним извне через переменные (ссылки, указатели) типа D запрещен;

  • Только друзья и члены D могут преобразовывать D* в B*, и D& в В&, и D в B;

  • Наследники класса D не знают о его базе В.

Защищенное наследование. class D: protected B {...}:

  • открытые и защищенные члены класса В могут использоваться только функциями-членами и друзьями класса D, а также могут использоваться функциями-членами и друзьями классов наследников D. Доступ к ним извне через переменные (ссылки, указатели) типа D запрещен;

  • Только друзья и члены D, а также члены и друзья классов-наследников D могут преобразовывать D* в B*, и D& в В&, и D в B.

Открытое наследование. class D: public B{...}:

  • Открытые и защищенные члены могут использоваться функциями-членами и друзьями класса D, а также могут использоваться функциями-членами и друзьями классов наследников D;

  • Открытые члены В доступны через переменные (ссылки и указатели) типа D;

  • Всем разрешено осуществлять преобразование типа D* в B*, и D& в В&, и D в B.

Исключения - средство С++ для отделения генерации информации от ее обработки.

Функция terminate(). Вызывается при разрушении стека:

  • если выбрасывается исключение во время обратной раскрутки стека при уже выброшенном исключении;

  • если вызывается throw вне блока перехвата исключения;

  • если произошло исключение, но оно не было перехвачено;

  • если конструктор глобального статического объекта завершился аварийно с выбросом исключения.

set_terminate позволяет установить обработчик terminate.

bool uncaught_exception() проверяет было ли исключение перехвачено (можно ли вызвать throw).

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

void f() thow(Exception) {}

Если функция пытается выбросить объект, не являющееся объектом типа Exception или его наследником, то произойдет вызов функции ловушки std::unexpected(), которая по умолчанию вызывает std::terminate(), но может быть переопределена программистом.

Проверка осуществляется на этапе исполнения, а не компиляции, проверка на этапе компиляции отдана на усмотрение разработчикам сред.

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

Виртуальная функция делается “чистой” при помощи инициализатора =0.

Абстрактный класс - класс, содержащий одну или несколько чисто виртуальную функцию.

Динамическое приведение типов. dynamic_cast<T> (expr):

  • Применим только для полиморфных типов;

  • Позволяет безопасно приводить тип от базового класса к производному, а также между родственниками;

  • Может применяться для приведения указателей и ссылок;

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

Недостатки использования препроцессора:

  • Генерация кода “шаблонного” класса или функции происходит до процесса синтаксического анализа, и таким образом, не используется статическая проверка типов на стадии “инстанцирования” кода “шаблона”;

  • Код “шаблонного” класса всегда генерируется полностью, в не зависимости от того, какие члены используются, а какие - нет. Всегда происходит явное инстанцирование такого “шаблона”;

  • Отсутствует возможность специализации шаблонов;

  • Препроцессор С плохо совместим с основными концепциями и идеями С++, и его чрезмерное использование, как правило, приводит к трудно поддерживаемому и развиваемому коду.

Недостатки подхода с общим корнем:

  • Необходимость в явном приведении типа при извлечении объектов из контейнера;

  • Трудность защиты от использования разнородных объектов внутри контейнера;

  • Ограниченность функционала по манипуляции с объектами внутри “обобщенного” класса исключительно контрактом, предусмотренным в базовом классе;

  • В С++ отсутствует выделенный базовый для всех типов корневой класс;

  • Отсутствие возможности работы в контейнерах со значениями встроенных типов;

  • Высокие накладные расходы во время исполнения.

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

Специализация шаблона - версия шаблона для конкретного аргумента шаблона.

Порождающий(родовой) тип - шаблонный класс.

Конкретизация шаблона(инстанцирование) - процесс генерирования типов (классов) с помощью шаблонного класса по заданным аргументам шаблона.

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

Параметрический полиморфизм происходит на стадии компиляции:

  • перегрузка функций;

  • инстанцирование шаблонов.

Виртуальный полиморфизм:

  • выбор реализации виртуальной функции во время исполнения на основе реального типа объекта.

Преимущества шаблонов С++:

  • Хорошо совместимы с концепцией строгой типизации и проверки совместимости типов на стадии инстанцирования кода и компиляции “обобщенных” классов и функций;

  • На столько же эффективны в плане производительности, как и “жестко заданные” обычные типы, в качестве параметров шаблонов при инстанцировании можно использовать встроенные типы;

  • Скорость компиляции и работы системы разработки при использовании шаблонов на столько же высока, как и при использовании обычных “жестко заданных” типов;

  • Поддержка уточнения и наследования;

  • Совместно с механизмом исключений и пространствами имен делают С++ очень мощным ОО инструментом для написания сложных программных систем.

Правила разрешения перегрузки шаблонов:

  • Ищется набор специализаций шаблонов функций, принимается решение какие аргументы были бы использованы, если бы в текущей области видимости не было других шаблонов функций и обычных функций с тем же именем;

  • Если могут быть вызваны два шаблона функции и один из них более специализирован, чем другой, на последующих этапах только он и рассматривается;

  • Разрешается перегрузка для этого набора функций, а также для любых обычных функций(в соответствии с правилами разрешения перегрузки для обычных функций). Если аргументы функции шаблона были определены путем выведения по фактическим аргументам шаблона, к ним нельзя применять “продвижение”, стандартные и определяемые пользователем преобразование типа;

  • Если и обычная функция, и специализация подходят одинаково хорошо, то предпочтение отдается обычной функции;

  • Если ни одного соответствия не найдено или процесс оканчивается нахождением двух или более одинаково хорошо подходящими вариантами, то выдается соответствующая ошибка компиляции.

Разрешение неоднозначности:

  • Явная квалификация;

  • Добавление подходящих объявлений.

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

Аллокатор - специальный класс (шаблон), который ответственен за выделение памяти и конструирование объектов.

Итератор - объект, позволяющий перебирать все элементы коллекции без учёта особенностей её реализации.