Программирование >>  Операторы преобразования типа 

1 ... 36 37 38 [ 39 ] 40 41 42 ... 239


который может использоваться, например, при объявлении множества, сортирующего свои элементы по этому критерию. Реализация критерия сортировки в виде объекта функции описана на с. 296.

Объекты функций

Функциональные аргументы, передаваемые алгоритмам, не обязаны быть функциями. Они могут быть объектами, которые ведут себя как функции. Такие объекты называются объектами функций, или функторами. Иногда объект функции справляется с ситуацией, в которой обычная функция не работает. Объекты функций часто используются в STL, причем некоторые являются очень полезными.

Понятие объекта функции

Объекты функций - еще один пример унифицированного программирования и концепции чистой абстракции. В соответствии с этой концепцией все, что ведет себя как функция, является функцией. Следовательно, если определить объект, который ведет себя как функция, он может использоваться в качестве функции.

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

functlon(argl.arg2): Вызов функции

Следовательно, если мы хотим, чтобы объект вел себя подобным образом, необходимо обеспечить возможность его вызова в программе с круглыми скобками и передачей аргументов. Да, такое вполне возможно (в С++ вообще редко встречается что-нибудь невозможное). От вас лишь потребуется определить оператор () с соответствующими типами параметров:

class X { public;

Определение оператора вызов функции возвращаемое зиачение operatorC) (аргументы) const;

Теперь объекты этого класса ведут себя как функции и могут вызываться в программе:

X fo;

fo(argl.arg2); Вызов оператора О для объекта функции fo

Такой вызов эквивалентен следующему: fo.operator()(argl.arg2); Вызов оператора О для объекта функции fo



Ниже приведен более полный пример - версия рассмотренной ранее программы с обычной функцией (см. с. 129), переработанная для использования объекта функции:

stl/foreach2.cpp Iinclude <iostreai]i> Iinclude <vector> Iinclude <algorithm> using namespace std;

Простой объект функции для вывода передаваемого аргумента class Printlnt { public:

void OperatorO (int elem) const { cout elem :

int mainO {

vector<int> coll:

Вставка эпемонтов со значениями от 1 до 9 for (int i=l: 1<=9; ++i) { col 1.push back(1);

Вывод всех элементов

for each (coll.beginO. coll.endO. Интервал PrintlntO): Операция

cout endl:

Класс Printlnt определяет объект, для которого вызывается оператор () с аргументом int. Выражение Printlnt() в следующей команде создает временный объект этого класса, передаваемый алгоритму for each() в качестве аргумента:

for each (coll .boginO. coll.endO. PrintlntO);

Алгоритм for each() определяется примерно так:

namespace std {

template <class Iterator, class Operation

Operation for each (Iterator act. Iterator end. Operation op)

while (act != end) { Пока не достигнут конец интервала

op(*act); - вызвать орО для текущего элемента

++act: - перемостить итератор к следующему

) элементу

return op:



Алгоритм for each() использует временный объект функции ор, чтобы для каждого элемента делать вызов op(*act). Если третий параметр является обычной функцией, она просто вызывается с аргументом *act. Если третий параметр является объектом функции, вызывается оператор () объекта функции ор с аргументом *act. Таким образом, в приведенной программе алгоритм for each() вызывает операторную функцию

printint:;operator()(*act)

На первый взгляд непонятно, зачем это нужно. Возникает ощущение, что объекты функций - конструкция странная, непонятная, а то и вовсе бессмысленная. Действительно, объекты функций усложняют программу. Но они способны на большее, чем функции, обладая рядом несомненных достоинств.

О Объект функции - это шумная функция . Объекты, которые ведут себя как указатели, называются умными указателями . По аналогии объекты, которые ведут себя как функции, можно назвать умными функциями , поскольку их возможности не ограничиваются вызовом оператора (). Объекты функций могут представ.яять другие функции и иметь другие атрибуты, а это означает, что объекты функций обладают состоянием. Одна и та же функция, представленная объектом функции, в разные моменты времени может находиться в разных состояниях. У обычных функций такая возможность отсутствует. Из этого следует одно из достоинств объектов функций - возможность их инициализации на стадии выполнения перед вызовом/использованием.

О Каждому объекту функции соответствует свой тип. Обычные функции обладают разными типами только при различиях в их сигнатурах. С другой стороны, объекты функций могут иметь разные типы даже при полном совпадении сигнатур. Это открывает новые возможности для унифицированного программирования с применением шаблонов, потому что функциональное поведение может передаваться как параметр шаблона. Например, это позволяет контейнерам разных типов использовать единственный объект функции в качестве критерия сортировки. Тем самым предотвращается возможное присваивание, слияние и сравнение коллекций, использующих разные критерии сортировки. Вы даже можете спроектировать иерархию объектов функций, например, для определения нескольких специализированных версий одного общего критерия.

О Объекты функгщй обычно работают быстрее функций. Шаблоны обычно лучше оптимизируются, поскольку на стадии компиляции доступно больше информации. Следовательно, передача объекта функции вместо обычной функции часто повышает быстродействие программы.

В оставшейся части этого подраздела приводятся несколько примеров, доказывающих, что объекты функций действительно умнее обычных функций. Дополнительные примеры и подробности приводятся в главе 8, полностью посвященной объектам функций. В частности, вы узнаете, насколько полезной бывает передача функционального поведения в качестве параметра шаблона.



1 ... 36 37 38 [ 39 ] 40 41 42 ... 239

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика