- •Тема 1.Понятие технологии программирования (2 часа). 3
- •Тема 2. Основные концепции ооп (2 часа). 7
- •Тема 3. Конструкторы и деструкторы (2 часа). 12
- •Тема 5. Дружественные функции (friend functions) (2 часа) 32
- •Тема 6. Обработка исключительных ситуаций (2 часа) 44
- •Тема 8. Производные классы (2 часа) 76
- •Тема 9. Виртуальные функции (2 часа) 83
- •Тема 10. Множественное наследование. Производные классы векторов (2 часа) 90
- •Тема 12. Шаблоны функций и классов. 128
- •Тема 14. Применение оо-подхода в базах данных 148
- •Тема 1.Понятие технологии программирования (2 часа).
- •1.1. Предмет изучения курса ооп
- •1.2. Исторический экскурс
- •1.3. Основные технологии программирования
- •1.4. Заключение
- •Тема 2. Основные концепции ооп (2 часа).
- •2.1. Объекты и классы
- •2.1.1.Понятие класса объектов
- •2.1.2. Основные характеристики состояния класса
- •2.1.3. Понятие инкапсуляции свойств объекта
- •2.1.4. Структура глобальной памяти класса и глобальные методы класса
- •2.1.5. Интерфейс класса
- •2.1.6. Функции-члены класса
- •2.2. Понятие наследования (Inheritance)
- •2.3. Понятиеполиморфизма
- •Тема 3. Конструкторы и деструкторы (2 часа).
- •3.1. Для чего нужны конструкторы
- •3.2. Использование конструкторов «по умолчанию»
- •3.3. Использование деструкторов
- •3.4. Демонстрация последовательности работы конструкторов и деструкторов
- •3.5. Конструктор копирования
- •3.6. Определение операции присваивания
- •3.6.1. Пример использования конструктора копирования.
- •3.7.1. Краткий обзор библиотеки stl
- •3.7.2. Вектора
- •3.8. Inline-подстановка
- •4.1. Перегрузка операторов
- •4.1.1. Пример на перегрузку операторов
- •4.1.2. Общие принципы перегрузки операторов
- •4.1.3. Бинарные и Унарные Операции
- •4.2. Пример с перегрузкой операторов
- •Тема 5. Дружественные функции (friend functions) (2 часа)
- •5.1. Примеры использования дружественных функций
- •5.2. Особенности перегрузки префиксной и постфиксной форм унарных операций
- •5.3. Статические члены данных
- •5.4. Перегрузка операторов new, new[], delete, delete[]
- •Void* operator new(size_t размер){ код оператора
- •Void operator delete(void* p){ код оператора }
- •Void* operator new[](size_t размер){ код оператора return указатель_на_память; }
- •Void operator delete[](void* p){ код оператора }
- •Тема 6.Обработка исключительных ситуаций(2 часа)
- •6.1. Применение try, catch, throw
- •6.2. Синтаксис и семантика генерации и обработки исключений
- •6.3. Обработка исключений
- •6.4. Обработка исключений при динамическом выделении памяти
- •6.5. Функции, глобальные переменные и классы поддержки механизма исключений
- •6.6. Конструкторы и деструкторы в исключениях
- •7.1 Строковые типы
- •7.1.1. Преобразования, определяемые классом
- •7.1.2. Встроенный строковый тип
- •7.1.3 Класс string
- •7.2. Пример строкового класса с перегруженными операторами и дружественными функциями
- •Тема8.Производные классы (2 часа)
- •8.1. Определение производного класса
- •8.2. Правила использования атрбутов доступа
- •8.3. Конструкторы и деструкторы производных классов
- •Тема 9. Виртуальные функции (2часа)
- •9.1. Определение виртуальных методов
- •9.2. Абстрактные классы
- •9.3. Таблицы виртуальных методов (функций)
- •9.4. Выводы
- •Тема 10. Множественное наследование. Производные классы векторов (2 часа)
- •10.1. Множественное наследование
- •10.2. Отношения между классами
- •10.2.3. Ассоциация
- •10.2.4. Агрегирование
- •10.2.5. Наследование
- •10.3. Библиотека графических объектов (пример)
- •10.3.1. Динамический полиморфизм и наследование интерфейсов
- •10.3.2.Абстрактные классы
- •10.3.3. Множественное наследование в библиотеке графичкских фигур.
- •10.3.4. Иерархия классов библиотеки графичкских фигур
- •10.3.5. Таблица наследования
- •10.3.6. Диаграмма модулей
- •10.3.7.Директивы препроцессора
- •10.4. Производные классы векторов
- •10.5. Операции над векторами
- •11.1. Потоковый ввод-вывод
- •11.1.1. Классы потоков
- •11.1.2. Стандартные потоки
- •11.2.Опрос и установка состояния потока
- •11.3.Перегрузка операций извлечения и вставки в поток
- •11.4.Переадресация ввода-вывода
- •11.5. Операции помещения в поток и извлечения из потока
- •11.6.Форматирование потока
- •11.7.Файловый ввод-вывод с использованием потоков
- •11.8.Бесформатный ввод-вывод
- •11.9.Часто применяемые функции библиотеки ввода / вывода
- •11.10.Файлы с произвольным доступом
- •11.11. Буферизация
- •11.12. Заключение
- •Тема 12. Шаблоны функций и классов.
- •12.1 Шаблоны функций
- •12.2. Шаблоны классов
- •12.3. Размещение определений шаблонов в многомодульных программах
- •12.4. Полиморфные вектора
- •13.1 Область видимости
- •13.1.1. Локальная область видимости
- •13.2. Глобальные объекты и функции
- •13.2.1. Объявления и определения
- •13.2.2. Несколько слов о заголовочных файлах
- •13.3. Локальные объекты
- •13.3.1. Автоматические объекты
- •13.3.2. Регистровые автоматические объекты
- •13.3.3. Статические локальные объекты
- •13.4. Динамически размещаемые объекты
- •13.4.1. Динамическое создание и уничтожение единичных объектов
- •13.5. Определения пространства имен а
- •Тема 14. Применение оо-подхода в базах данных
- •14.1. Реляционные базы данных
- •14.2 Объектно-ориентированные базы данных (ообд)
- •14.3. Гибридные базы данных
- •Рекомендуемая литература
Тема 12. Шаблоны функций и классов. 128
12.1 Шаблоны функций 128
12.2. Шаблоны классов 132
12.3. Размещение определений шаблонов в многомодульных программах 135
12.4. Полиморфные вектора 135
ТЕМА 13. ВИДИМОСТЬ ЭЛЕМЕНТОВ В С++.СТАТИЧЕСКАЯ И СВОБОДНАЯ ПАМЯТЬ(2 часа). 137
13.1 Область видимости 137
13.1.1. Локальная область видимости 138
13.2. Глобальные объекты и функции 141
13.2.1. Объявления и определения 141
13.2.2. Несколько слов о заголовочных файлах 143
13.3. Локальные объекты 144
13.3.1. Автоматические объекты 144
13.3.2. Регистровые автоматические объекты 144
13.3.3. Статические локальные объекты 144
13.4. Динамически размещаемые объекты 146
13.4.1. Динамическое создание и уничтожение единичных объектов 146
13.5. Определения пространства имен А 148
Тема 14. Применение оо-подхода в базах данных 148
14.1. Реляционные базы данных 148
14.2 Объектно-ориентированные базы данных (ООБД) 148
14.3. Гибридные базы данных 149
Рекомендуемая литература 150
Тема 1.Понятие технологии программирования (2 часа).
Предмет изучения ООП. Исторический экскурс. Основные технологии программирвания.
1.1. Предмет изучения курса ооп
Курс "Объектно-ориентированное программирование" направлен, прежде всего, на изучение и освоение навыков проектирования программ с использованием удобных механизмов, фиксирущих поведение реального мира так, что деталии разработки скрыты, что позволяет разработчику мыслить в терминах, приcущих этой конкретной задаче, а не программированию.
В рамках курса предусматривается изучение и практическое закрепление навыков разработки программ средствами компилятора Turbo C++ или (Borland C++). С++ относится к классу гибридных объектно-ориентированных языков и позволяет:
- достичь приемлемой эффективности результирующих программ;
- обеспечить совместимость с уже написанными прикладными программами;
- сохранить огромный опыт действующих программистов;
- обеспечить эволюционных переход к использованию концепций ООП.
1.2. Исторический экскурс
Начало бурного развития идей ООП обычно связывают с появлением в начале 80-х годов системы Smaltalk-80, разработанной в научно-исследовательском центре PARC фирмы Xerox, которая является "чистой" объектно-ориентированной системой. Сегодня ООП признается практически всеми как наиболее передовая технология программирования.В начале 80-х годов Бьян Страуступ предложил расширение языка С, которое включало средства поддержки идей ООП ("С с классами"), в 1983 г. в результате интенсивных исследований этот язык приобрел законченную форму объектно-ориентированного языка программирования и получил название С++.
Концепция ООП является естественным следствием развития технологий программированияи опирается на такие фундаментальные понятия какструктурность, модульную локализацию данных и абстрактные типы данных.
1.3. Основные технологии программирования
Под технологией (техно - искусство; логос - учение) программированияпонимается наука об оптимальных способах проведения процесса программирования, которая обеспечивает в заданных условиях получение программной продукции с заданными свойствами.
Первые работы по технологии программирования инициализируются в 1968 г. письмом Дейкстры (одного из авторов концепции структурного программирования), в котором он обратил внимание на то, что опытные программисты избегают использовать оператор goto в своих программах, а строят их как композицию трех-четырех операторов: присвоения, выбора, повторения, обращения к процедуре и так далее. Это небольшое письмо послужило началом целой эпохи в программировании, которая позже получила названиеструктурного программирования.
Структурные принципы построения программ были сформулированы в фундаментальных работах В.М.Глушкова по теории дискретных превращений (1964-1965гг.), в которых он не только определил основные структуры и правила их композиции, но и доказал фундаментальную теорему о возможности превращения произвольной программы в структурированную форму.
В структурном (или процедурном) программированиипрограммист мыслит как конструктор, в распоряжении которого есть некоторые небольшие полностью определенные типичные конструкции (структуры), правила соединения которых, заданы априори - сочленение, вложение друг в друга, разложение на составляющие. Структура - это или оператор языка программирования, или некоторая абстракция по управлению. Основной конструкцией структурного программирования является ветвление (или альтернатива):
if B then S1 else S2 endif
Характерно также использование операторов цикла: while B do Sилиrepeat S until B.
-
Акцент здесь делается на алгоритме, необходимом для выполнения требуемых вычислений.
Языки поддерживают эту парадигму, предоставляя средства для передачи аргументов функциям и возврату значений из функций.
При этом существуют две стратегии проектирования больших программ:
1) Стратегия проектирования сверху вниззаключается в том, что построение программного проекта начинается сверху с самых общих сведений о проекте и проводится по уровням шагами вниз до окончательной записи программы на языках программирования. На каждом уровне проектирования стратегия сверху вниз имеет в виду скомпонованность и готовность отдельных модулей (или "заглушек") и всей программы. «Заглушка» - маленькая функция, принимающая параметры реальной большой функции и возвращающая необходимые значения (необходима до тех пор, пока не будет написана и отлажена реальная функция).
Такая стратегия позволяет получить логически стройные программные проекты, существенно уменьшить сложность их налаживания и, главное, вносить изменения в реализацию отдельных частей проекта (в части алгоритма реализации, языка программирования и др.) без нарушения работоспособности остальных частей проекта.
2) Стратегия проектирования снизу вверхзаключается в том, что за основу берутся уже готовые программные модули, из которых строятся другие, более сложные или отсутствующие в начальном наборе, таким образом, чтобы в итоге выполнилось поставленное задание.Недостаткомэтой стратегии является то, что логически стройная программная система выходит лишь в результате нескольких итераций. Использование такой стратегии бывает оправданно лишь при наличии большого процента ранее заготовленных программных модулей.
При разработке модульных программ применяются два метода проектирования – нисходящее и восходящее. При нисходящем проектировании разработка программного комплекса идет сверху вниз.
На первом этапе разработки кодируется, тестируется и отлаживается головной модуль, который отвечает за логику работы всего программного комплекса. Остальные модули заменяются заглушками, имитирующими работу этих модулей. Применение заглушек необходимо для того, чтобы на самом раннем этапе проектирования можно было проверить работоспособность головного модуля. На последних этапах проектирования все заглушки постепенно заменяются рабочими модулями.
При восходящем проектировании разработка идет снизу вверх. На первом этапе разрабатываются модули самого низкого уровня. На следующем этапе к ним подключаются модули более высокого уровня и проверяется их работоспособность. На завершающем этапе проектирования разрабатывается головной модуль, отвечающий за логику работы всего программного комплекса. Методы нисходящего и восходящего программирования имеют свои преимущества и недостатки.
Недостатки нисходящего проектирования:
Необходимость заглушек.
До самого последнего этапа проектирования неясен размер программного комплекса и его эксплутационные характеристики, за которые, как правило, отвечают модули самого низкого уровня.
Преимущество нисходящего проектирования – на самом начальном этапе проектирования отлаживается головной модуль (логика программы).
Преимущество восходящего программирования – не нужно писать заглушки.
Недостаток восходящего программирования – головной модуль разрабатывается на завершающем этапе проектирования, что порой приводит к необходимости дорабатывать модули более низких уровней.
На практике применяются оба метода. Метод нисходящего проектирования чаще всего применяется при разработке нового программного комплекса, а метод восходящего проектирования – при модификации уже существующего комплекса.
Наибольшее распространение до конца 70-х годов получило структурное проектирование по методу сверху вниз. Однако "оказалось, что структурный подход не работает, если объем программы превышает приблизительно 100 000 строк".
С течением времени акцент при разработке программ сместился от проектирования процедур в сторону организации данных. Помимо прочего это явилось отражением факта увеличения размеров программ. Набор связанных процедур, вместе с данными, которые они обрабатывают, часто называетсямодулем. Парадигмой программирования теперь становится:
-
Реши, какие требуются модули.
Разбей программу так, чтобы скрыть данные в модулях.
Эта парадигма известна, как «принцип сокрытия данных». А принцип построения программ – модульным программированием.
В модульном программированииакцент делается на разбивку программы на модули так, чтобы данные (обрабатываемые модулем) были спрятаны в нем. Эта доктрина в значительной степени повысила эффективность порождаемого кода.
Давайте вспомним, каким образом подключаются стандартные библиотеки С++:
#include < .h>
- в библиотеке includeлежат только прототипы функций, сами функции в объектном (двоичном) коде находятся в библиотеке lib, таким образом, будучи защищены от вторжения извне.
Эволюция техники модульного программирования привела к появлению объектно-ориентированногостиля программирования, который во многом унифицировал процесс создания программных продуктов. Одной из причин появления ООП явилась необходимость зщиты данных.
Объектно - ориентированное программирование - это подход, в основе которого лежит представление о том, что программную систему необходимо проектировать как совокупность объектов, которые взаимодействуют друг с другом, рассматривая каждый объект как экземпляр определенного класса, причем классы при этом образуют иерархию. ООП отображает топологию таких языков высокого уровня, как Smaltalk, Pascal, C++ и Ада.
Ключевой идеейООП является создание языковых средств, которые на базе концепции абстрактных типов данных позволяют создавать новые классы программных объектов, образующих вычислительную среду, ориентированную на конкретную предметную область. При этом любая абстракция предметной области должна быть доступна для понимания пользователя – спецалиста любой области (не программиста), например, произведение векторов, записанное в виде:
С=A*B будет более понятным, чем C=A.mul(B).
Естественный способ моделирования предметной отрасли- это выделение в ней классов (типов) объектов, которые владеют с точки зрения разрешимой задачи одинаковыми свойствами и поведением и установления между такими классами объектов родовых соотношений. При использовании ООП программист строит прикладную программу путем определения (программным путем) классов объектов, состав, свойства и поведение которых отвечают модели предметной облласти. При этом общность их свойств отображается формированием иерархии родовых связей. Таким образом, ОО-программу можно рассматривать как особенную модель предметной отрасли.
Парадигма программирования теперь звучит так:
-
Реши, какие требуются классы; обеспечь полный набор операций для каждого класса; ясно вырази общность через наследование.