Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
STL5 / lab4-iterators / lab4-iterators.doc
Скачиваний:
13
Добавлен:
10.04.2015
Размер:
299.01 Кб
Скачать

Итераторы

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

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

Например, концепция итераторов позволяет использовать один и тот же алгоритм сортировки абсолютно без изменений для любого контейнера, допускающего изменение элементов: и для массива, и для списка, и даже, к примеру, для неупорядоченного бинарного дерева – за последовательный доступ к элементам будет отвечать итератор (только при этом надо понимать, что ОТСОРТИРОВАНО дерево будет с точки зрения последовательности, представляющей его элементы, какой это будет иметь смысл для самого дерева – на первый взгляд не очень понятно). Также можно заставить итератор работать как фильтр и перебирать не все элементы, а лишь удовлетворяющие некоторому условию (в STLфильтрующих итераторов нет, но такой итератор можно написать самостоятельно). Можно добавить и более сложную функциональность и заставить итератор, к примеру, изменять коллекцию – см. часть «Адаптеры итераторов», итераторы вставки.

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

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

Основные понятия

Итераторы STL - это объекты, которые имеют operator*, возвращающий текущий элемент последовательности, этот элемент является объектом некоторого класса или встроенного типаT, называемого типом значения (value type) итератора. Для каждого типа итератораX, для которого определено равенство, имеется соответствующий знаковый целочисленный тип, называемый типом расстояния (distanсe type) итератора.

Для перемещения итератора на следующий элемент используется operator++(). В разных типах итераторов могут быть определены и другие операции:operator--()(для двунаправленного итератора), увеличение на произвольное число (итератор произвольного доступа) и т.п. – см часть «Классификация итераторов» и «Свойства итераторов различного типа».

operator*() иoperator++() - это основные операции для всех типов итераторовSTL.

Значения итератора, для которых operator*определён, называютсяразыменовываемыми(dereferenceable).

Существуют значения итераторов, указывающие за последний элемент коллекции – так называемые законечные (past-the-end) значения. Законечные значения не являются разыменовываемыми и используются для обозначения конца последовательности.

Итератор jназываетсядоступным (reachable) из итератораi, если для итераторов данного типа определена операция равенства и существует конечная (возможно, нулевая) последовательность операцийj++; j++; …., после которойj==i.Если итераторыiиjотносятся к разным коллекциям1, то ни один из них не доступен из другого. В противном случае если итераторы должны перебирать все элементы коллекции (или одинаковое их подмножество), то очевидно, что либоiдоступен изj, либоjдоступен изi.

Последовательность элементов задается парой итераторов [i,j),указывающих на начало и конец. При этом элемент, указываемыйi, включается, аj– нет, т.е. последним рассматривается элемент, предыдущийj. Большинство алгоритмов библиотекиSTL, а также методы классов оперируют с последовательностями такого вида.Например,классvectorсодержит метод, который заполняет вектор содержимым, взятым из последовательности элементов заданных парой итераторов [first;last). Элемент, указываемыйfirstвключается, а указываемыйlastнет.

template <class T, class A=allocator<T>>

class vector

{

public:

// заполнение вектора элементами последовательности задаваемой

// итераторами [first:last)

template <class In>

void assign(In first, In last);

};

Последовательность [i,i)пуста. Последовательность[i,j)допустима, если и только еслиjдоступен изi. Результат применения алгоритмов библиотеки к недопустимым последовательностям не определён.

Идея использования итератора может быть проиллюстрирована следующим примером (приведенный ниже пример не является кодом, использующим STL, это некий абстрактный код, цель которого продемонстрировать концепцию итераторов)

// В примере видно, что print_sequenceне имеет никакой информации

// о той последовательности, которую обрабатывает, что позволяет

// обрабатывать с ее помощью любую последовательность представимую

// порой итераторов

typedef int *iterator;

voidprint_sequence(iterator first, iterator last)

{

while(first != last)

{

cout << *first << endl;

first++;

}

}

int array[100] = {/*...*/};

print_sequence(&array[0], &array[100]); // распечатать все

print_sequence(&array[10], &array[20]); // распечатать часть

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

Классы и функции, связанные непосредственно с итераторами (без привязки к конкретному контейнеру), находятся в заголовочном файле <iterator>.

Соседние файлы в папке lab4-iterators