
- •Объектно-ориентированное программирование:
- •Содержание
- •Новый тип данных – класс
- •1.2. Доступность компонентов класса
- •1.3. Конструктор и деструктор
- •1.4. Компоненты-данные и компоненты-функции
- •1.4.1. Данные – члены класса
- •1.4.2. Функции – члены класса
- •1.4.3. Константные компоненты-функции
- •1.4.4. Статические члены класса
- •Указатели на компоненты класса
- •1.5.1. Указатели на компоненты-данные
- •1.5.2.Указатели на компоненты-функции
- •1.6. Указатель this
- •1.7. Друзья классов
- •7.1. Дружественная функция
- •1.7.2. Дружественный класс
- •1.8. Определение классов и методов классов
- •2. Наследование
- •2.1. Определение производного класса
- •2.2. Конструкторы и деструкторы производных классов
- •2.3. Виртуальные функции
- •2.4. Абстрактные классы
- •2.5. Включение объектов
- •2.6. Включение и наследование
- •2.7. Множественное наследование
- •2.8. Локальные и вложенные классы
- •2.9. Пример программы для Microsoft Visual Studio
- •2.10. Упражнения
- •3. Перегрузка операций
- •3.1. Перегрузка унарных операций
- •3.2. Перегрузка бинарных операций
- •3.4. Перегрузка операции вызова функции
- •3.5. Перегрузка операции присваивания
- •3.6. Перегрузка операции new
- •3.7. Перегрузка операции delete.
- •3.8. Основные правила перегрузки операций
- •3.9. Примеры программ
- •4. Шаблоны функций и классов
- •4.1. Шаблоны функций
- •4.2. Шаблоны классов
- •4.3. Компонентные функции параметризованных классов
- •4.4. Примеры программ.
- •5. Обработка исключительных ситуаций
- •5.2. Получение дополнительной информации об исключении
- •5.3. Определение типа исключения
- •5.4. Иерархия исключений
- •5.5. Спецификация функций, обрабатывающих исключения
- •6. Потоковые классы
- •6.1. Библиотека потоковых классов
- •6.3. Стандартные потоки ввода-вывода
- •6.4. Форматирование
- •6.5. Манипуляторы
- •6.6. Ввод-вывод объектов пользовательских классов
- •6.7. Определение пользовательских манипуляторов
- •6.8. Пользовательские манипуляторы с параметрами
- •6.9. Использование макросов для создания манипуляторов
- •6.10. Состояние потока
- •6.11. Неформатированный ввод-вывод
- •6.12. Файловый ввод-вывод
- •7.1. Пространство имен
- •7.2. Динамическая идентификация типов
- •7.3. Безопасное приведение типа
- •8. Стандартная библиотека шаблонов
- •8.1. Введение в stl
- •Парадигму обобщенного программирования можно сформулировать следующим образом:
- •8.2. Итераторы
- •8.3. Классы-контейнеры
- •Iterator find(const key_type&k)
- •Iterator lower_bound(const key_type&k)
- •Iterator upper_bound(const key_type&k)
- •8.4. Контейнер vector
- •8.5. Многомерные массивы
- •8.6. Ассоциативные контейнеры
- •8.7. Объекты-функции
- •8.8. Алгоритмы
- •I. Немодифицирующие операции
- •II. Модифицирующие операции
- •III. Сортировка
- •IV. Работа с множествами
- •V. Минимумы и максимумы
- •VI. Перестановки
4.2. Шаблоны классов
Шаблон класса используется для построения родового класса. При создании родового класса создается целое семейство родственных классов, которые можно применять к любому типу данных. Таким образом, тип данных, которым оперирует класс, указывается в качестве параметра при создании объекта, принадлежащего к этому классу. Принципиальное преимущество параметризованного класса заключается в том, что он позволяет определить члены класса один раз, но применять класс к данным любых типов. Подобно тому, как класс определяет правила построения и формат отдельных объектов, шаблон класса определяет способ построения отдельных классов. В определении класса, входящего в шаблон, имя класса является не именем отдельного класса, а параметризованным именем семейства классов.
Наиболее широкое применение шаблоны классов находят при создании контейнерных классов. Фактически создание контейнеров является одной из основных причин, по которым были введены в употребление шаблоны.
Контейнерными классами (контейнерами) называются классы, в которых хранятся организованные данные. Например, массивы и связные списки. Преимущество, даваемое определением параметризованных контейнерных классов, заключается в том, что, как только логика, необходимая для поддержки контейнера, определена, он может применяться к любым типам данных без необходимости его переписывания. Например, параметризованный контейнер связного списка можно использовать для построения списков, содержащих почтовые адреса, заглавия книг, названия автомобилей.
Общая форма объявления параметризованного класса:
template <class тип_данных> class имя_класса { . . . };
Здесь тип_данных представляет собой имя типа шаблона, которое в каждом случае конкретизации будет замещаться фактическим типом данных. При необходимости можно использовать более одного параметризованного типа данных, используя список с разделителем – запятой. В пределах определения класса имя тип_данных можно использовать в любом месте.
Создав параметризованный класс, можно создать конкретную реализацию этого класса, используя следующую общую форму:
имя_класса <тип> имя_объекта;
Здесь тип представляет собой имя типа данных, над которыми фактически оперирует класс, и заменяет собой переменную тип_данных.
Перечислим основные свойства шаблонов классов:
Компонентные функции параметризованного класса автоматически являются параметризованными. Их не обязательно объявлять как параметризованные с помощью template.
Дружественные функции, которые описываются в параметризованном классе, не являются автоматически параметризованными функциями, т.е. по умолчанию такие функции являются дружественными для всех классов, которые организуются по данному шаблону.
Если friend-функция содержит в своем описании параметр типа параметризованного класса, то для каждого созданного по данному шаблону класса имеется собственная friend-функция.
В рамках параметризованного класса нельзя определить friend-шаблоны (дружественные параметризованные классы).
С одной стороны, шаблоны могут быть производными (наследоваться) как от шаблонов, так и от обычных классов, с другой стороны, они могут использоваться в качестве базовых для других шаблонов или классов.
Определенные пользователем имена в описании шаблона по умолчанию рассматриваются как идентификаторы переменных. Чтобы имя рассматривалось как идентификатор типа, оно должно быть определено внутри шаблона или в окружающей области определения через ключевое слово typename.
Шаблоны функций, которые являются членами классов, нельзя описывать как virtual.
Локальные классы не могут содержать шаблоны в качестве своих элементов.