Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

}

Очевидно, что функция

Larger_than
должна удовлетворять двум условиям.

• Ее можно вызывать как предикат, например

pred(*first)
.

• Она может хранить значение, например

31
или
x
, передаваемое при вызове.

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

class Larger_than {

int v;

public:

Larger_than(int vv) : v(vv) { } // хранит аргумент

bool operator(int x) const { return x>v; } // сравнение

};

Следует отметить, что это определение представляет собой именно то, что мы требовали от предиката. Теперь осталось понять, как это работает. Написав выражение

Larger_than(31)
, мы (очевидно) создаем объект класса
Larger_than
, хранящий число
31
в члене
v
. Рассмотрим пример.

find_if(v.begin,v.end,Larger_than(31))

Здесь мы передаем объект

Larger_than(31)
алгоритму
find_if
как параметр с именем
pred
. Для каждого элемента v алгоритм
find_if
осуществляет вызов

pred(*first)

Это активизирует оператор вызова функции, т.е. функцию-член operator, для объекта-функции с аргументом

*first
. В результате происходит сравнение значения элемента, т.е.
*first
, с числом
31
.

Мы видим, что вызов функции можно рассматривать как результат работы оператора

, аналогично любому другому оператору. Оператор
называют также оператором вызова функции (function call operator) или прикладным оператором (application operator). Итак, оператор
в выражении
pred(*first)
эквивалентен оператору
Larger_than::operator
, точно так же, как оператор
[]
в выражении
v[i]
эквивалентен оператору
vector::operator[]
.

21.4.1. Абстрактная точка зрения на функции-объекты

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

class F { // абстрактный пример объекта-функции

S s; // состояние

public:

F(const S& ss):s(ss) { /* устанавливает начальное значение */ }

T operator (const S& ss) const

{

// делает что-то с аргументом ss

// возвращает значение типа T (часто T — это void,

// bool или S)

}

const S& state const { return s; } // демонстрирует

// состояние

void reset(const S& ss) { s = ss; } // восстанавливает

// состояние

};

Объект класса

F
хранит данные в своем члене
s
. По мере необходимости объект-функция может иметь много данных-членов. Иногда вместо фразы “что-то хранит данные” говорят “нечто пребывает в состоянии”. Когда мы создаем объект класса
F
, мы можем инициализировать это состояние. При необходимости мы можем прочитать это состояние. В классе
F
для считывания состояния предусмотрена операция
state
, а для записи состояния — операция
reset
. Однако при разработке объекта-функции мы свободны в выборе способа доступа к его состоянию.

Разумеется, мы можем прямо или косвенно вызывать объект-функцию, используя обычную систему обозначений. При вызове объект-функция

F
получает один аргумент, но мы можем определять объекты-функции, получающие столько параметров, сколько потребуется.

Использование объектов-функций является основным способом параметризации в библиотеке STL. Мы используем объекты-функции для того, чтобы указать алгоритму поиска, что именно мы ищем (см. раздел 21.3), для определения критериев сортировки (раздел 21.4.2), для указания арифметических операций в численных алгоритмах (раздел 21.5), для того, чтобы указать, какие объекты мы считаем равными (раздел 21.8), а также для многого другого. Использование объектов-функций — основной источник гибкости и универсальности алгоритмов.

  • Читать дальше
  • 1
  • ...
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: