На этом шаге мы приведем общие сведения об итераторах.
Итератором называется объект, предназначенный для перебора элементов контейнера STL (всех или
некоторого подмножества). Итератор представляет некоторую позицию в контейнере. Ниже перечислены основные операторы,
работу с которыми поддерживает итератор.
- * - получение элемента в текущей позиции итератора. Если элемент состоит из отдельных членов, для обращения к ним
непосредственно через итератор используется оператор ->. (На некоторых старых платформах итераторы еще не
поддерживают оператор ->). - ++ - перемещение итератора к следующему элементу. Многие итераторы также поддерживают перемещение в обратном
направлении, для чего используется оператор --. - == и != - проверка совпадений позиций, представленных двумя итераторами.
- = - присваивание итератора (позиции элемента, на которую он ссылается).
Этот набор операторов в точности соответствует интерфейсу обычных указателей С и C++ при переборе элементов массива.
Различие заключается в том, что итераторы могут быть умными указателями, обеспечивающими перебор в более сложных
контейнерных структурах данных. Внутреннее поведение итератора зависит от структуры данных, в которой осуществляется перебор.
Таким образом, каждая разновидность контейнеров обладает собственным итератором. В каждом контейнерном классе тип итератора
определяется в виде вложенного класса. В результате все итераторы обладают одинаковым интерфейсом, но имеют разные типы.
В итоге мы приходим к концепции унифицированного программирования: операции выполняются с одинаковым интерфейсом, но с
разными типами, что позволяет использовать шаблоны для определения унифицированных операций, работающих с произвольными
типами, которые поддерживают заданный интерфейс.
Во всех контейнерных классах поддерживаются базовые функции, применяемые для перебора элементов при помощи итераторов.
Ниже перечислены важнейшие из этих функций.
- begin() - возвращает итератор, установленный в начало последовательности элементов контейнера. Началом считается
позиция первого элемента (если он есть). - end() - возвращает итератор, установленный в конец последовательности элементов контейнера. Концом считается
позиция за последним элементом.
Итак, функции begin() и end() определяют полуоткрытый интервал, который содержит первый элемент, но выходит за
пределы последнего элемента (рисунок 1).
Рис.1. Функции begin() и end()
Полуоткрытый интервал обладает двумя достоинствами:
- появляется простое условие завершения перебора в контейнере: цикл продолжается до тех пор, пока не будет достигнута позиция end();
- предотвращается специальная обработка пустых интервалов, поскольку в пустом интервале begin() совпадает с end().
На следующем шаге мы рассмотрим небольшой пример использования итераторов.