Программирование >>  Инициализация объектов класса, структура 

1 ... 185 186 187 [ 188 ] 189 190 191 ... 395


/ / простеая форма класса объекта-функции class less equal ten {

public:

bool operator() ( int val ) { return val <= 10; }

некоторое значение меньше или равно 10:

Теперь такой объект-функцию можно использовать точно так же, как предопределенный. Вызов алгоритма count if() с помощью нашего объекта-функции выглядит следующим образом:

count if( vec.begin(), vec.end(), less equal ten() ); Разумеется, возможности этого класса весьма ограничены. Попробуем применить

count if( vec.begin(), vec.end(), отрицатель, чтобы подсчитать, сколько в контейнере элементов, больших 10:

not1(less eal then ()));

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

class less equal value {

public:

less equal value( int val ) : val( val ) {} bool operator() ( int val ) { return val <= val; }

private:

int val;

указанной пользователем величиной: };

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

count if( vec.begin(), vec.end(), less eal value( 25 ));

Разрешается реализовать класс и без конструктора, если параметризовать его значением, с которым производится сравнение:

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



template < int val > class less equal value {

public:

bool operator() ( int val ) { return val <= val; }

Вот как надо было бы вызвать такой класс для подсчета числа элементов, меньших или равных 25:

count if( vec.begin(), vec.end(), less eal value<25>());

(Другие примеры определения собственных объектов-функций можно найти в Приложении.)

Упражнение 12.4

Используя предопределенные объекты-функции и адаптеры, создайте объекты-функции для решения следующих задач:

(a) Найти все значения, большие или равные 1024.

(b) Найти все строки, не равные pooh .

(c) Умножить все значения на 2. Упражнение 12.5

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

12.4. Еще раз об итераторах

Следующая реализация шаблона функции не компилируется. Можете ли вы сказать,

в таком виде это не компилируется template < typename type >

count( const vector< type > &vec, type value ) {

int count = 0;

vector< type >::iterator iter = vec.begin();

while ( iter != vec.end() )

if ( *iter == value ) ++count;

return count;

почему?

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



vector< int >::iterator iter0 = vec0.begin();

vec1 - константный итератор:

vector< int >::const iterator iter1 = vec1.begin();

Разумеется, присваивание константному итератору неконстантного разрешено всегда.

правильно: инициазация константного итератора неконстантна

Например:

vector< int >::const iterator iter2 = vec0.begin();

12.4.1. Итераторы вставки

Вот еще один фрагмент программы, в котором есть тонкая, но серьезная ошибка. Видите

int ia[] = { 0, 1, 1, 2, 3, 5, 5, 8 };

vector< int > ivec( ia, ia+8 ), vres;

...

поведение программе! во время волнения не определено

ли вы, в чем она заключается?

unique copy( ivec.begin(), ivec.end(), vres.begin() );

предотвращения подобной ситуации язык требует, чтобы итератор, связанный с const-

правильно: это компилируется без ошибок

вектором, был константным. Мы можем сделать это следующим образом:

vector< type>::const iterator iter = vec.begin();

Требование, чтобы с const-контейнером был связан только константный итератор, аналогично требованию о том, чтобы const-массив адресовался только константным указателем. В обоих случаях это вызвано необходимостью гарантировать, что содержимое const-контейнера не будет изменено.

Операции begin() и end() перегружены и возвращают константный или неконстантный итератор в зависимости от наличия спецификатора const в объявлении контейнера. Если

vector< int > vec0;

дана такая пара объявлений:

const vector< int > vec1;

то при обращениях к begin() и end() для vec0 будет возвращен неконстантный, а для



1 ... 185 186 187 [ 188 ] 189 190 191 ... 395

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