Shape
, рассмотренных в главах 16–19, мы буквально работали с разными формами (классами Text
, Circle
и Polygon
) с помощью интерфейса, определенного классом Shape
. Используя класс vector
, мы фактически работаем со многими векторами (например, vector
, vector
и vector
) с помощью интерфейса, определенного шаблонным классом 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
{
for (int i=0; i
}
Здесь мы вызываем виртуальную функцию (draw()
) из базового класса (Shape
) с помощью другой виртуальной функции — это определенно объектно-ориентированное программирование. Однако указатели Shape*
хранятся в объекте класса vector
, который является параметризованным типом, значит, мы одновременно применяем (простое) обобщенное программирование.
Для получения непревзойденно гибких и высокопроизводительных программ.
• Используйте шаблоны, когда производительность программы играет важную роль (например, при интенсивных вычислениях в реальном времени; подробнее об этом речь пойдет в главах 24 и 25).
• Используйте шаблоны, когда гибкость сочетания информации, поступающей от разных типов, играет важную роль (например, при работе со стандартной библиотекой языка C++; эта тема будет обсуждаться в главах 20 и 21).