- •Лекция 1 Динамическая память и интеллектуальные указатели.
- •Лекция 2
- •Лекция 3
- •Исчерпание памяти
- •Лекция 4 Smart-pointer для обработки исключений
- •Создание собственного кода удаления
- •Класс unique_ptr
- •Класс weak_ptr
- •Использование динамических массивов
- •Смарт поинтеры и динамические массивы
- •Класс allocator
- •Тема 2. Обработка исключительных ситуаций
- •Лекция 7
- •Класс Exception
- •Лекция 8
- •Потоки, буферы и файл iostream
- •Перегруженная операция вставки
- •Лекция 9
- •Ввод с помощью cin
- •Тема 4. Файловый ввод/вывод
- •Лекция 10
- •Режимы открытия файла
- •Бинарные файлы
- •Лекция 11
- •Тема 5. Библиотека шаблонов Standart Template Library (stl)
- •Шаблонный класс Vector
- •Лекция 12
- •Цикл for , основанный на диапазоне
- •Обобщённое программирование
- •Лекция 13
- •Виды итераторов
- •Входные итераторы
- •Однонаправленные итераторы
- •Двунаправленные итераторы
- •Произвольного доступа
- •Лекция 14 Двунаправленные итераторы
- •Виды контейнеров
- •Лекция 15 Разработка с использованием Java-платформы
- •Этапы развития языка Java
- •Байт-код
- •Особенности языка Java
- •Программная платформа и виртуальная машина Java
- •Особенности разработки и исполнения объектно-ориентированных приложений на Java Сборка мусора в Java
- •Пакет jdk
- •Ide для работы на Java
- •Особенности настройки работы платформы Java
- •Запуск приложения на языке Java без ide
- •Особенности лексики Java
- •Примитивные типы данных Java
- •Переменные
- •Объявление переменной
- •Область и срок действия переменной
- •Преобразование и приведение типов. Автоматическое приведение и продвижение типов в выражениях. Логические выражения. Арифметические операции
- •Логические операции
- •Предшествование операций
- •Управляющие операторы
- •Операторы выбора Условный оператор if
- •Операторы цикла
- •Разновидность цикла for в стиле for each
- •Применение оператора instanceof
- •Принципы ооп
Входные итераторы
Входной итератор предназначен для считывания значений из контейнера. Разыменование входного итератора должно приводить к чтению элементов из контейнера, но не обязательно должно позволять модифицировать это значение. Алгоритмы, требующие входных итераторов, не изменяют содержимое контейнера. Входной итератор должен обеспечивать доступ ко всех значениям контейнера. Нет никакой гарантии, что второй проход по элементам контейнера с помощью входного итератора будет выполнен в той же последовательности, потому что это определяет контейнер. Не существует гарантий, что после увеличения значения входного итератора на 1 его предыдущее значение останется доступным для разыменования.
Входной итератор должен быть однонаправленным и не зависеть от значений итератора из предшествующего прохода или предшествующих значений этого же итератора. Его можно инкрементировать, но нельзя декрементировать. Таким образом вывод программы является вводом для контейнера.
Выходной итератор аналогичен входному за исключением того, что его разыменование дает возможность изменения значения, но не всегда его чтения.
Выходной итератор может применяться для алгоритмов однократного прохода с доступом только для записи. А входной только для чтения
Однонаправленные итераторы
Предназначен для перемещения по элементам контейнера только вперед, но при каждом проходе он обязательно перебирает элементы контейнера в той же последовательности. После инкрементирования однонаправленного итератора предыдущее значение по прежнему можно разыменовать, что даст то же самое значение для многопроходных алгоритмов. Позволяет как чтение, так и модификацию данных.
Двунаправленные итераторы
Обладают всеми свойствами однонаправленных, но еще поддерживают декремент, как префиксный, так и постфиксный.
Произвольного доступа
Сортировка, поиск требуют возможности перехода на произвольный элемент контейнера, что требует соответствующий итератор. Итератор произвольного доступа обладает всем от двунаправленного, а так же операцией произвольного перемещения, операцией отношения для возможности упорядочивания элементов.
Алгоритмы, записанные в терминах определенного вида итераторов не могут получать любой другой, но контейнер, поддерживающий произвольный доступ, может использовать нижестоящий.
12 мая 2021
Лекция 14 Двунаправленные итераторы
Идея использования разных видов итераторов состоит в том, чтобы написать алгоритм, использующий итератор с минимально необходимыми требованиями, что позволит применять его с максимальным множеством различных контейнеров. Так, например, функция find за счет использования в ней входного итератора может применяться с любым контейнером, который содержит читаемые значения. А сорт может выполняться только с контейнерами, поддерживающими произвольный доступ.
Итераторы являются обобщением указателей и отвечают всем их требованиям. Итераторы образуют интерфейс для алгоритмов stl. Алгоритм copy может копировать из одного контейнера в другой, поскольку в качестве итератора можно применять указатели на массив. Первые 2 аргумента – диапазон, который необходимо скопировать, а третий – куда копировать. Первые 2 входные и более совершенные итераторы, а послейдний – выходной. Функция copy всегда переписывает данные в контейнере назначения и контейнер назначения должен быть достаточно велик, чтобы поместить все копируемые элементы.
Класс ostream_iterator можно создать, подключив заголовочный файл iterator.
ostream_iterator<int, char> out_iter(cout, “ “).
int – тип данных, отправляемые в выходной поток
char – тип, используемый выходным потоком (cout)
Первый аргумент конструктора cout определяет используемый выходной поток, вместо него можно быть использовать fstream.
Для обычного указателя запись
*out_iter++ = 15;
означала бы присваивание значения указателю out_iter с последующим инкрементированием, но для объекта типа out stream iterator говорит об отправке значения “15” в поток, добавления разделителя и перемещения на следующую позицию вывода.
Istream_iterator требует типа данных, который будет прочитан и второй – символьный тип, используемый входным потоком.
Использование аргумента конструктора cin означает считывание данных с клавиатуры. Отсутствие аргументов у этого итератора означает ошибку ввода, как способ завершения считывания данных.
Итераторы специального назначения:
reverse_iterator;
back_insert_iterator;
front_insert_iterator;
insert_iterator;
Reverse_iterator представляет собой класс инкрементирование которого вызывает декремент. Класс vector имеет метод rbegin() возвращающий обратный итератор, который указывает на элемент, находящийся за последним значимым. Метод rend(), который возвращает итератор на начало. Методы rbegin() и end() возвращают одно и то же значение за последним элементом, но разного типа: rbegin - reverse_iterator, end - iterator.
Методы rend() и begin() возвращают одно и то же значение (итератор, указывающий на первый элемент), но разного типа : reverse_iterator и iterator соответственно.
Обратные указатели обязательно сначала нужно декрементировать, а затем разыменовывать для предотвращения разыменования элемента, стоящего за последним значимым.
Когда есть возможность выбора между явным объявлением итератора и использованием функции STL , то следует отдавать предпочтение второму подходу. Итераторы back_insert_iterator, front_insert_iterator часто называются просто итераторами вставки. Многие алгоритмы STL передают свои результаты по адресу, указанным выходным итератором, при этом некоторые функции предпринимают попытку изменения размера контейнера назначения, некоторые – нет. Эта особенность может быть решена использованием трех операторов вставки, преобразуя процесс копирования в процесс вставки. Вставка всегда добавляет новые элементы не перезаписывая существующие, при этом используется автоматическое выделение памяти для обеспечения необходимого размера контейнера.
Итератор back_insert_iterator вставляет элементы в конец контейнера, front_insert_iterator в начало, insert_iterator перед позицией, указанной в аргументе конструктора. Все эти три итератора соответствуют концепции выходного итератора.
Ограничения свойственные эти трем итератором:
back_insert_iterator может применяться только к контейнерам, которые допускают вставку в конец быстро, ? термин быстрый относится к алгоритмам с постоянным временем, класс вектор позволяет это делать.
front_insert_iterator может использоваться только с контейнерными типами, допускающие вставку в начало за постоянное время. Класс вектор не позволяет это делать, а класс queue позволяет.
Insert_iterator можно применять для вставки данных в начало вектор, но использование front_insert_iterator будет выполняться быстрее с теми типами контейнеров, которые поддерживают его применение. Insert_iterator позволяет преобразовать копирующий алгоритм в алгоритм вставки.
При объявлении итератора обязательно указывать тип контейнера в связи с тем, что итератор будет применять соответствующий метод контейнера. Например, код конструктора back_insert_iterator будет исходить из предположения о том, что существует метод в контейнере (push_back) для переданного ему типа.
Объявление итератора insert_iterator содержит дополнительный аргумент для указания позиции вставки.
Объявление итератора insert_iterator содержит дополнительный аргумент для указания позиции ставки.