Здавалка
Главная | Обратная связь

Использование функторов.



Как вам известно из прошлых уроков, в библиотеке STL существует понятие функторов. Сейчас мы познакомимся с этим понятием поближе.

Функторы (иначе говоря, функциональные объекты) - это специализированный вид классов, которые включают в себя перегруженный оператор вызова функции. Как правило, функтор можно применить везде, где требуется функция. Проще говоря, когда должна быть вызвана функция, вызывается перегруженный оператор вызова функции.(оператор "круглые скобки").

Основным отличием функтора от обычной функции, является возможность хранения некоторого значения по принципу статических переменных. Принцип работы таков:

Первое обращение к функтору возбуждает вызов конструктора, который инициализирует сам функтор. При использовании обычной функции приходится хитрить, чтобы выполнить начальную инициализацию. Кроме того, некоторые источники говорят о том, что вызов функтора выполняется гораздо быстрее, чем вызов обычной функции с помощью указателя.

Рассмотрим пример, который позволит нам более детально разобраться в назначении функторов. Реализуем таблицу умножения. Требования следующие: первый множитель увеличивается слева направо, второй - сверху вниз. Это классический пример на алгоритм итерации.

Разберем алгоритм выполнения задания:

  • Генерация строки с набором частных для одного числа и повторение генерации для нескольких чисел.
    • Инициализация контейнера-списка (или вектора).
    • Заполнение контейнера-списка (или вектора).
    • Вывод значений контейнера-списка (или вектора)на экран.
  • Создание функтора, который должен последовательно генерирует число, начиная от заданного, и каждый раз увеличивает его на определенное значение.
// библиотека для работы алгоритмов// мы еще будем рассматривать её более подробно сегодня #include <algorithm> #include <iostream>// библиотека контейнера списка#include <list>using namespace std; /*Функциональный объект, содержащий два поля:1. для хранения значения приращения (delta) 2. для текущего значения генерируемого числа (current)*/class addNumberFrom{ int delta; int current;/*Конструктор класса инициализирует значение приращения и текущее значение.Последнее может быть опущено, и тогда оно будет считаться равным 0*/public: addNumberFrom(int number, int from = 0):delta(number), current(from) {} /*Основа функтора - перегруженный оператор вызова функции - прибавляет значение приращения к текущему генерируемому числу*/ int operator()() { return current += delta; }}; // Вывод заголовка для таблицы умножения. void main(){ cout<<"TABLE:"<<"\n\n"; cout << "----------" <<"\n\n"; for(int i=1; i<=10; i++) { // Cоздание контейнера-списка. list<int> l(10); /* Вызов алгоритма generate_n. Естественно, сам он не может ничего генерировать, однако последовательно перебирает значения, диапазон которых задан начальным итератором и количеством элементов списка. Для записи числа в каждое значение вызывается функция, на которую ссылается третий параметр: */ generate_n(l.begin(), l.size(), addNumberFrom(i)); /* Но мы вместо функции подставляем перегруженный оператор вызова функции - объект addNumberFrom. Если вызов происходит впервые, то вызывается конструктор объекта. Он инициализирует поле delta значением переменной i, а поле current - значением по умолчанию второго параметра конструктора, т. е. 0. Таким образом, контейнер-список заполняется произведениями числа в переменной i и множителями от 1 до 10. В алгоритме generate_n используется метод size(), который возвращает количество элементов в списке. Если имеются начальный и конечные итераторы, тогда лучше воспользоваться алгоритмом generate. */ // Собственно показ числа из контейнера-списка copy(l.begin(), l.end(), ostream_iterator<int>(cout,"\t")); }}

Надеемся, пример помог вам понять функторы более глубоко. Теперь отметим, что зачастую различные арифметические и логические операции, а также операции сравнения могут реализовываться стандартными средствами STL, то есть набором уже существующих, встроенных функторов:

  • Арифметические функторы
    • plus сложение x + y
    • minus вычитание x - y
    • multiplies умножение x х y
    • divides деление x / y
    • modulus взятие остатка x % y
    • negate обращение знака - x
  • Функторы сравнения
    • equal_to равно x == y
    • not_equal_to не равно x != y
    • greater больше x > y
    • less меньше x < y
    • greater_equal больше или равно x => y
    • less_equal меньше или равно x <= y
  • Логические функторы
    • logical_and логическое "и" x && y
    • logical_or логическое "или" x || y
    • logical_not логическое "не" ! x
Предыдущая Оглавление Следующая
Предыдущая Оглавление Следующая






©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.