Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:
• Поиск значения в объекте класса
• Поиск объекта класса
• Графическое изображение экспериментальных данных с точными значениями не должно отличаться от графического изображения экспериментальных данных с округленными значениями.
• Копирование файла не должно отличаться от копирования вектора.
Учитывая сказанное, мы хотим писать код, удовлетворяющий следующим условиям:
• его легко читать;
• легко модифицировать;
• он имеет систематический характер;
• он короткий;
• быстро работает.
• Единообразный доступ к данным:
• независимость от способа хранения данных;
• независимость от типа данных.
• Доступ к данным, безопасный с точки зрения типа:
• легкое перемещение по данным;
• компактное хранение данных.
• Скорость работы:
• поиск данных;
• добавление данных;
• удаление данных.
• Стандартные версии большинства широко распространенных алгоритмов таких как
Библиотека STL обеспечивает не только эти возможности. Мы изучим эту библиотеку не только потому, что она представляет собой очень полезный набор инструментов, но и потому, что является примером максимальной гибкости и эффективности. Библиотека STL была разработана Алексом Степановым (Alex Stepanov) для того, чтобы создать базу для универсальных, правильных и эффективных алгоритмов, работающих с разнообразными структурами данных. Ее целью были простота, универсальность и элегантность математики.
Итак, рассмотрев мотивы и цели, перейдем к описанию основных определений из библиотеки STL, а затем изучим примеры их применения для более простого создания более совершенного кода для обработки данных.
20.3. Последовательности и итераторы
Основным понятием в библиотеке STL является последовательность. С точки зрения авторов этой библиотеки, любая коллекция данных представляет собой последовательность. Последовательность имеет начало и конец. Мы можем перемещаться по последовательности от начала к концу, при необходимости считывая или записывая значение элементов. Начало и конец последовательности идентифицируются парой итераторов. Итератор (iterator) — это объект, идентифицирующий элемент последовательности.
Последовательность можно представить следующим образом:
Здесь
• Что такое итератор? Это довольно абстрактное понятие.
• Итератор указывает (ссылается) на элемент последовательности (или на ячейку, следующую за последним элементом).
• Два итератора можно сравнивать с помощью операторов
• Значение элемента, на который установлен итератор, можно получить с помощью унарного оператора
• Итератор на следующий элемент можно получить, используя оператор
Допустим, что
Очевидно, что идея итератора связана с идеей указателя (см. раздел 17.4). Фактически указатель на элемент массива является итератором. Однако многие итераторы являются не просто указателями; например, мы могли бы определить итератор с проверкой выхода за пределы допустимого диапазона, который генерирует исключение при попытке сослаться за пределы последовательности
ПОПРОБУЙТЕ
Напишите функцию
Итераторы используются в качестве средства связи между нашим кодом (алгоритмами) и нашими данными. Автор кода знает о существовании итераторов (но не знает, как именно они обращаются к данным), а поставщик данных предоставляет итераторы, не раскрывая всем пользователям детали механизма хранения данных. В результате получаем достаточно независимые друг от друга алгоритмы и контейнеры. Процитируем Алекса Степанова: “Алгоритмы и контейнеры библиотеки STL потому так хорошо работают друг с другом, что ничего не знают друг о друге”. Вместо этого и алгоритмы, и контейнеры знают о последовательностях, определенных парами итераторов.
Иначе говоря, автор кода больше не обязан ничего знать о разнообразных способах хранения данных и обеспечения доступа к ним; достаточно просто знать об итераторах. И наоборот, если поставщик данных больше не обязан писать код для обслуживания огромного количества разнообразных пользователей, ему достаточно реализовать итератор для данных. На базовом уровне итератор определен только операторами