- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
19.3.2. Обобщенное программирование
Шаблоны — это основа для обобщенного программирования на языке С++. По существу, простейшее определение обобщенного программирования на языке С++ — это программирование с помощью шаблонов. Хотя, конечно, это определение носит слишком упрощенный характер. Не следует давать определения фундаментальных понятий программирования в терминах конструкций языка программирования. Эти конструкции существуют для того, чтобы поддерживать технологии программирования, а не наоборот. Как и большинство широко известных понятий, обобщенное программирование имеет несколько определений. Мы считаем наиболее полезным самое простое из них.
• Обобщенное программирование — это создание кода, работающего с разными типами, заданными в виде аргументов, причем эти типы должны соответствовать специфическим синтаксическим и семантическим требованиям.
Например, элементы вектора должны иметь тип, который можно копировать (с помощью копирующего конструктора и копирующего присваивания). В главах 20-21 будут представлены шаблоны, у которых аргументами являются арифметические операции. Когда мы производим параметризацию класса, мы получаем шаблонный класс (class template), который часто называют также параметризованным типом (parameterized type) или параметризованным классом (parameterized class). Когда мы производим параметризацию функции, мы получаем шаблонную функцию (function template), которую часто называют параметризованной функцией (parameterized function), а иногда алгоритмом (algorithm). По этой причине обобщенное программирование иногда называют алгоритмически ориентированным программированием (algorithm-oriented programming); в этом случае основное внимание при проектировании переносится на алгоритмы, а не на используемые типы.
Поскольку понятие параметризованных типов играет такую важную роль в программировании, мы попытаемся в дальнейшем немного разобраться в этой запутанной терминологии. Это даст нам возможность избежать недоразумений, когда мы встретим знакомые понятия в другом контексте.
Данную форму обобщенного программирования, основанную на явных шаблонных параметрах, часто называют параметрическим полиморфизмом (parametric polymorphism). В противоположность ей полиморфизм, возникающий благодаря иерархии классов и виртуальным функциям, называют специальным полиморфизмом (ad hoc polymorphism), а соответствующий стиль — ориентированным программированием (см. разделы 14.3-14.4). Причина, по которой оба стиля программирования называют полиморфизмом (polymorphism), заключается в том, что каждый из них дает программисту возможность создавать много версий одного и того же понятия с помощью единого интерфейса. Полиморфизм по-гречески означает “много форм”. Таким образом, вы можете манипулировать разными типами с помощью общего интерфейса. В примерах, посвященных классу Shape, рассмотренных в главах 16–19, мы буквально работали с разными формами (классами Text, Circle и Polygon) с помощью интерфейса, определенного классом Shape. Используя класс vector, мы фактически работаем со многими векторами (например, vector<int>, vector<double> и vector<Shape*>) с помощью интерфейса, определенного шаблонным классом vector.
Существует несколько различий между объектно-ориентированным программированием (с помощью иерархий классов и виртуальных функций) и обобщенным программированием (с помощью шаблонов). Наиболее очевидным является то, что выбор вызываемой функции при обобщенном программировании определяется компилятором во время компиляции, а при объектно-ориентированном программировании он определяется во время выполнения программы. Рассмотрим примеры.
v.push_back(x); // записать x в вектор v
s.draw(); // нарисовать фигуру s
Для вызова v.push_back(x) компилятор определит тип элементов в объекте v и применит соответствующую функцию push_back(), а для вызова s.draw() он неявно вызовет некую функцию draw() (с помощью таблицы виртуальных функций, связанной с объектом s; см. раздел 14.3.1). Это дает объектно-ориентированному программированию свободу, которой лишено обобщенное программирование, но в то же время это делает обычное обобщенное программирование более систематическим, понятным и эффективным (благодаря прилагательным “специальный” и “параметрический”).
Подведем итоги.
• Обобщенное программирование поддерживается шаблонами, основываясь на решениях, принятых на этапе компиляции
• Объектно-ориентированное программирование поддерживается иерархиями классов и виртуальными функциями, основываясь на решениях, принятых на этапе выполнения программы.
Сочетание этих стилей программирования вполне возможно и полезно. Рассмотрим пример.
void draw_all(vector<Shape*>& v)
{
for (int i=0; i<v.size(); ++i) v[i]–>draw();
}
Здесь мы вызываем виртуальную функцию (draw()) из базового класса (Shape) с помощью другой виртуальной функции — это определенно объектно-ориентированное программирование. Однако указатели Shape* хранятся в объекте класса vector, который является параметризованным типом, значит, мы одновременно применяем (простое) обобщенное программирование.
Но довольно философии. Для чего же на самом деле используются шаблоны?
Для получения непревзойденно гибких и высокопроизводительных программ.
• Используйте шаблоны, когда производительность программы играет важную роль (например, при интенсивных вычислениях в реальном времени; подробнее об этом речь пойдет в главах 24 и 25).
• Используйте шаблоны, когда гибкость сочетания информации, поступающей от разных типов, играет важную роль (например, при работе со стандартной библиотекой языка C++; эта тема будет обсуждаться в главах 20 и 21).
Шаблоны имеют много полезных свойств, таких как высокая гибкость и почти оптимальная производительность, но, к сожалению, они не идеальны. Как всегда, преимуществам сопутствуют недостатки. Основным недостатком шаблонов является то, что гибкость и высокая производительность достигаются за счет плохого разделения между “внутренностью” шаблона (его определением) и его интерфейсом (объявлением). Это проявляется в плохой диагностике ошибок, особенно плохими являются сообщения об ошибках. Иногда эти сообщения об ошибках в процессе компиляции выдаются намного позже, чем следовало бы.
При компиляции программы, использующей шаблоны, компилятор “заглядывает” внутрь шаблонов и его шаблонных аргументов. Он делает это для того, чтобы извлечь информацию, необходимую для генерирования оптимального кода. Для того чтобы эта информация стала доступной, современные компиляторы требуют, чтобы шаблон был полностью определен везде, где он используется. Это относится и к его функциям-членам и ко всем шаблонным функциям, вызываемым из них. В результате авторы шаблонов стараются разместить определения шаблонов в заголовочных файлах. На самом деле стандарт этого не требует, но пока не будут разработаны более эффективные реализации языка, мы рекомендуем вам поступать со своими шаблонами именно так: размещайте в заголовочном файле определения всех шаблонов, используемых в нескольких единицах трансляции.
Мы

