•
string и vector, демонстрирующие сильную зависимость между абстракциями данных и параметризацией, используемой в обобщенном программировании. Слово “абстракция” используется в названии этой парадигмы потому, что взаимодействие с типом осуществляется посредством интерфейса, а не прямого доступа к его реализации.•
•
high(), описанная в главе 20. Алгоритмы find() и sort() из библиотеки являются классическими алгоритмами поиска и сортировки, выраженными в очень общей форме с помощью обобщенного программирования. См. также примеры в главах 20-21.
Рассмотрим пример: классический класс Shape
void draw_all(vector
{
for(int i = 0; i
}
Этот фрагмент кода действительно выглядит “довольно объектно-ориентированным”. Он основан на иерархии классов и вызове виртуальной функции, при котором правильная функция draw()
Shape находится автоматически; иначе говоря, для объекта класса Circle он вызовет функцию Circle::draw(), а для объекта класса Open_polyline — функцию Open_polyline::draw(). Однако класс vector по существу является конструктивным элементом обобщенного программирования: он использует параметр (тип элемента), который выясняется на этапе компиляции. Следует подчеркнуть, что для итерации по всем элементам используется алгоритм из стандартной библиотеки.void draw_all(vector
{
for_each(v.begin(),v.end(),mem_fun(&Shape::draw));
}
Третьим аргументом функции for_each()
f(x), а не функцию-член, вызываемую с помощью синтаксической конструкции p–>f(). Следовательно, для того чтобы указать, что на самом деле мы хотим вызвать функцию-член (виртуальную функцию Shape::draw()), необходимо использовать стандартную библиотечную функцию mem_fun() (раздел Б.6.2). Дело в том, что функции for_each() и mem_fun(), будучи шаблонными, на самом деле не очень хорошо соответствуют объектно-ориентированной парадигме; они полностью относятся к обобщенному программированию. Еще интереснее то, что функция mem_fun() является автономной (шаблонной) функцией, возвращающей объект класса. Другими словами, ее следует отнести к простой абстракции данных (нет наследования) или даже к процедурному программированию (нет сокрытия данных). Итак, мы можем констатировать, что всего лишь одна строка кода использует все четыре фундаментальных стиля программирования, поддерживаемых языком C++.