Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_otvety_k_ekzamenu.doc
Скачиваний:
55
Добавлен:
13.04.2015
Размер:
786.94 Кб
Скачать

49. Функциональные объекты stl. Простые функциональные объекты. Стандартные функциональные объекты. Связыватели std::bind.

Функциональный объект представляет собой любую сущность, которая может быть применена к нулю или большему количеству элементов для получения значения и/или изменения состояния вычислений. В программировании на C++ любая обычная функция отвечает этому определению, но ему же отвечает и объект любого класса (или структуры), который перегружает оператор вызова функции o p e r a to r ().Приведем пример работы функциональных объектов с двумя аргументами функции. Определим шаблонный класс PairSelect, содержащий функцию печати, которая выводит меньший элемент пары в соответствии с определенным нами отношением «меньше чем», задаваемым параметром шаблона. Также в виде параметра шаблона мы зададим тип элементов пары. Следующая программа использует два отношения упорядочения. Они реализованы в виде бинарных предикатов, то есть функций, которые имеют два аргумента и возвращают логическое значение. Наш первый бинарный предикат, LessThan, является шаблоном, поэтому он применим к любому типу, для которого определен оператор < Второй предикат, CompareLastDigits,является обычным, не шаблонным, функциональным классом, который практически совпадает с функциональным классом, определенным в последнем разделепредыдущей главы, только результат его вызова равен true,если последняя цифра первого аргумента меньше, чем у второго, и false - в противном случае.

// funobj3.cpp: Функция operator!) как

// бинарный предикат.

#include <iostream.h>

template <class T>

struct LessThan {

bool operator()(const T &x, const T &y)const

{ return x < y;

}

} ;

struct CompareLastDigits {

bool operator()(int x, int y)const

{ return x % 10 < у % 10;

}

};

Функциональные объекты 141

template <class Т, class Compare>

class PairSelect {

public:

PairSelect(const T &x, const T &y) : a(x), b(y){}

void PrintSmaller()const

{ cout << (Compare()(a, b) ? a : b) « endl;

}

private:

Т а , b ;

} ;

int main()

{ PairSelect<double, LessThan<double> > P (123.4, 98.7);

P.PrintSmaller(); // Вывод: 98.7

PairSelect<int, CompareLastDigits> Q (123, 98);

Q.PrintSmaller(); // Вывод: 123

return 0;

}

Эта программа сначала выводит значение 98.7, потому что оно меньше другого элемента объекта Q - 123.4. После этого она выводит 123, поскольку последняя цифра этого числа - 3 - меньше, чем последняя цифра числа 98. Одно из главных преимуществ заключается в том, что объекты, в отличие от обычных функций, могут хранить дополнительную информацию, которая затем может использоваться обобщенными алгоритмами или контейнерами. Связыватель (binder) применяется для преобразования бинарного функционального объекта в унарный путем связывания аргумента с некоторым определенным значением.В STL это достигается с помощью использования привяжи,которая является одним из видов адаптера функции. Чтобы превратить бинарный предикат в унарный, привязав его второй аргумент, мы используем привязку bind2nd.В нашем примере требуется использовать выражение bind2nd(less<int>(), 100) чтобы указать, что мы хотим считать только значения, меньшие 100. Следующая программа показывает, как это все работает // binder.срр: Использование адаптера bind2nd для подсчета, сколько из элементов массива меньше, чем 100.

♦include <iostream>

♦include <algorithm>

♦include <functional>

using namespace std;

int main()

{ int a [10] = {800, 3, 4, 600, 5, 6, 800, 71, 100, 2},

n = 0;

n = count_if(a, a + 10, bind2nd(less<int>(), 100));

cout << n « endl; // Вывод: 6

return 0;

}

Для п р и вязы ван и я первого аргумента сущ ествует п р и вязка bindXst. К примеру, заменим условие х < 100 эквивалентным условием 100 > х Этого можно добиться, привязав первый операнд у выражения у > х к значению 100. Следовательно, программа binder.срр выдаст тот же результат, если мы заменим вызов c o u n t if на следующий: n = count_if(a, а + 10, bindlst(greater<int>(), 100));

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]