
- •Структура дисциплины
- •Процедурное программирование
- •Объектно-ориентированное программирование
- •Обобщенное программирование
- •На пути к объектно-ориентированному программированию
- •Абстракция сущностей и процедурный язык программирования
- •Абстрактный тип данных
- •Организация класса
- •Определение и объявление класса
- •Члены класса
- •Маркеры доступа
- •Конструкторы
- •Понятие об объекте
- •Организация кода при работе с классами
- •Статические компоненты класса
- •Конструкторы. Детальное рассмотрение
- •Функции getter и setter
- •Виды отношений между классами
- •Отношение зависимость
- •Отношение целое / часть
- •Разработка класса b_1.
- •Конструктор умолчания.
- •Конструктор с параметрами
- •Конструктор копирования.
- •Деструктор
- •Реализация класса b_2_1.
- •Дружественные функции и дружественные классы
- •Особенности применения дружественных функций и классов
- •Перегрузка оператров
- •Перегрузка оператора присваивания
- •Реализация перегруженного оператора присваивания для класса Array
- •Перегрузка оператора индексирования
- •Понятие о константной функции
- •Константный вариант перегруженного оператора индексирования
- •Вычисление смешанных выражений
- •Наследование
- •Структура объекта порожденного класса
- •Доступ к элементам базового класса
- •Конструкторы порожденного класса
- •Порядок создания объекта порожденного класса
- •Перегруженный оператор присваивания порожденного класса
- •Вызов виртуальной функции из тела невиртуальной функции
- •Виртуализация функций не-членов класса
- •Идиома невиртуального интерфейса (nvi)
- •Реализация механизма виртуальных функций
- •Накладные расходы при работе с виртуальными функциями
- •Чисто виртуальные функции. Абстрактные базовые классы
- •Виртуальные деструкторы
- •Автономные и базовые классы
- •Чисто виртуальный деструктор
- •Дублирование подобъектов
- •Конструкторы при виртуальном наследовании
- •Работа с данными при виртуальном наследовании
- •Обработка исключительных ситуаций
- •Завершение или продолжение
- •Распределение обязанностей между разработчиком и клиентом
- •Генерация исключений
- •Объект исключения
- •Раскрутка стека
- •Спецификации исключений
- •Работа с обработчиками
- •Формат обработчика
- •Пример обработки исключений
- •Современная точка зрения на спецификации исключения
- •Шаблоны функций
- •Объявление и определение шаблона функции
- •Примеры объявлений и определений шаблонов функций
- •Инстанцирование шаблона функции
- •Неявное инстанцирование
- •Явное инстанцирование конкретной функции
- •Структура использования шаблона функции с явным инстанцированием
- •Перегрузка шаблона функции
- •Явная специализация шаблона функции
- •Шаблоны классов
- •Использование шаблона класса
- •Наследование и шаблоны
- •Шаблоны классов и отношение включения
- •Рекурсивное использование шаблонов классов
- •Друзья и шаблоны классов
- •Явная и частичная специализация шаблона класса
- •Алгоритмы
- •Алгоритм for_each
- •Функциональные объекты
- •Алгоритм copy
- •Алгоритм sort
- •Термины и определения
- •.Литература
Алгоритмы
Это существенная часть библиотеки STL. Алгоритмы более всего похожи на обычную библиотеку. Основное отличие их от традиционной библиотеки они (алгоритмы) реализованы в виде шаблонов функций.
Алгоритмы – это внешние функции, работающие с итераторами. Преимущество такого подхода состоит в следующем. Вместо того, чтобы разрабатывать такой алгоритм для каждого вида контейнера, достаточно реализовать его один раз для обобщенного контейнера.
Следует отметить один важный факт. В основе использования алгоритмов лежит скорее парадигма процедурного программирования, а не парадигма объектно-ориентированного программирования. При работе с алгоритмами данные разделяются на части, взаимодействующие через некоторый интерфейс.
Один из недостатков такого подхода состоит в том, что некоторые комбинации данных и алгоритмов могут оказаться недопустимыми и еще хуже, допустимыми, но мало эффективными.
Алгоритм for_each
Формат.
template <typename InIter, typename UnaryFunction> void for_each(InIter first, InIter last, UnaryFunction f);
Алгоритм for_each вызывает функцию f для каждого элемента последовательности, задаваемой двумя итераторами [first, last). Здесь f так называемая унарная функция. Унарная функция – это функция, принимающая один аргумент.
Пример 1. Имеется контейнер типа list<int>. Требуется организовать вывод элементов контейнера на дисплея с помощью алгоритма for_each.
#include<ostream> #include<list> #include<algoritm> using namespace std; void print(int x) { cout << x << ‘\t’; } int main() { int ar[] = {1, 3, 5, 7}; list<int> lst(ar, ar + n); for_each(lst.begin(), lst.end(), print); cout << endl; } // Вывод не экран дисплея 1 3 5 7
Проблема. Каким образом в случае необходимости передавать информацию в функцию f. Например, каким образом организовать вывод на экран дисплея не всех элементов контейнера, а только тех, которые удовлетворяют некоторому условию (например, только положительные элементы).
Выход из положения состоит в применение так называемых функциональных объектов.
Функциональные объекты
Функциональный объект – это экземпляр класса, в котором перегружен оператор функция: operator().
Пример 2. Дан контейнер типа list<int>. Вывести на экран дисплея элементы контейнера, значения которых не превышают величины a.
// директивы препроцессора // Класс, экземпляры которого являются объект-функциями class print_if { public: print_if(int a) : a_(a) { } void operator()(int value) { if(value <= a) cout << value << ‘\t’; } private: int a_; }; // Клиентский код int main() { int a; // Ввод a list<int> lst; // Работа с контейнером lst // Вывод с использованием алгоритма for_each for_each(lst.begin(), lst.end(), prinf_if(a)); // ... }
В третьем параметре алгоритма for_each создается анонимный (без имени) объект, а ожидается вызов функции. Особенностью класса print_if является наличие перегруженного оператора функция: operator(). Наличие этого перегруженного оператора и принимает во внимание компилятор. При выполнении алгоритма for_each в рассматриваемом примере для каждого элемента контейнера lst из диапазона, задаваемого первым и вторым параметрами алгоритма, будет выполняться перегруженный оператор функция.