Шаблон итератора
В объектно-ориентированном программировании — шаблон итератора это шаблон проектирования , в котором итератор используется для обхода контейнера и доступа к его элементам. Шаблон итератора отделяет алгоритмы от контейнеров; в некоторых случаях алгоритмы обязательно зависят от контейнера и поэтому не могут быть отделены.
Например, гипотетический алгоритм SearchForElement обычно может быть реализован с использованием итератора указанного типа, а не как алгоритм, специфичный для контейнера. Это позволяет SearchForElement использовать в любом контейнере, поддерживающем требуемый тип итератора.
Обзор
[ редактировать ]Итератор [1] шаблон проектирования — один из 23 известных Шаблоны проектирования «Банда четырех» которые описывают, как решать повторяющиеся проблемы проектирования для разработки гибкого и многократно используемого объектно-ориентированного программного обеспечения, то есть объектов, которые легче реализовать, изменить, протестировать и повторно использовать.
Какие проблемы может решить шаблон проектирования «Итератор»?
[ редактировать ]- Доступ к элементам агрегатного объекта и их перемещение должны осуществляться без раскрытия его представления (структур данных).
- Новые операции обхода должны быть определены для агрегатного объекта без изменения его интерфейса.
Определение операций доступа и обхода в агрегатном интерфейсе является негибким, поскольку оно связывает агрегат с конкретными операциями доступа и обхода и делает невозможным добавление новых операций. позже без необходимости изменения агрегатного интерфейса.
Какое решение описывает шаблон проектирования «Итератор»?
[ редактировать ]- Определите отдельный объект (итератор), который инкапсулирует доступ к агрегатному объекту и его обход.
- Клиенты используют итератор для доступа к агрегату и его обхода, не зная его представления (структур данных).
Различные итераторы могут использоваться для доступа к агрегату и его перемещения по-разному.
Новые операции доступа и обхода можно определить независимо, определив новые итераторы.
См. также класс UML и диаграмму последовательности ниже.
Определение
[ редактировать ]Суть шаблона «Итератор» заключается в том, чтобы «предоставить способ последовательного доступа к элементам агрегатного объекта, не раскрывая его базовое представление». [3]
Структура
[ редактировать ]Класс UML и диаграмма последовательности
[ редактировать ]
На приведенной выше UML классов диаграмме Client
класс относится (1) к Aggregate
интерфейс для создания Iterator
объект ( createIterator()
) и (2) к Iterator
интерфейс для перемещения по Aggregate
объект ( next(),hasNext()
).
Iterator1
класс реализует Iterator
интерфейс, обратившись к Aggregate1
сорт.
Диаграмма UML последовательности
показывает взаимодействие во время выполнения: Client
вызовы объектов createIterator()
на Aggregate1
объект, который создает Iterator1
объект и возвращает его
к Client
.
Client
использует тогда Iterator1
перемещаться по элементам Aggregate1
объект.
Диаграмма классов UML
[ редактировать ]
Пример
[ редактировать ]Некоторые языки стандартизируют синтаксис. Яркими примерами являются C++ и Python.
С++
[ редактировать ]C++ реализует итераторы с семантикой указателей этого языка. В C++ класс может перегружать все операции с указателями, поэтому можно реализовать итератор, который действует более или менее как указатель, включая разыменование, увеличение и уменьшение. Это имеет то преимущество, что алгоритмы C++, такие как std::sort
может быть немедленно применен к обычным старым буферам памяти, и нет необходимости изучать новый синтаксис. Однако для проверки равенства требуется «конечный» итератор, а не позволить итератору узнать, что он достиг конца. На языке C++ мы говорим, что итератор моделирует концепцию итератора .
Эта реализация C++11 основана на главе «Еще раз обобщая вектор». [5]
#include <iostream>
#include <stdexcept>
#include <initializer_list>
class Vector {
public:
using iterator = double*;
iterator begin() { return elem; }
iterator end() { return elem + sz; }
Vector(std::initializer_list<double> lst) :elem(nullptr), sz(0) {
sz = lst.size();
elem = new double[sz];
double* p = elem;
for (auto i = lst.begin(); i != lst.end(); ++i, ++p) {
*p = *i;
}
}
~Vector() { delete[] elem; }
int size() const { return sz; }
double& operator[](int n) {
if (n < 0 || n >= sz) throw std::out_of_range("Vector::operator[]");
return elem[n];
}
Vector(const Vector&) = delete; // rule of three
Vector& operator=(const Vector&) = delete;
private:
double* elem;
int sz;
};
int main() {
Vector v = {1.1*1.1, 2.2*2.2};
for (const auto& x : v) {
std::cout << x << '\n';
}
for (auto i = v.begin(); i != v.end(); ++i) {
std::cout << *i << '\n';
}
for (auto i = 0; i <= v.size(); ++i) {
std::cout << v[i] << '\n';
}
}
Вывод программы
1.21
4.84
1.21
4.84
1.21
4.84
terminate called after throwing an instance of 'std::out_of_range'
what(): Vector::operator[]
См. также
[ редактировать ]- Составной узор
- Контейнер (структура данных)
- Шаблон проектирования (информатика)
- Итератор
- Шаблон наблюдателя
Ссылки
[ редактировать ]- ^ Эрих Гамма; Ричард Хелм; Ральф Джонсон; Джон Влиссидес (1994). Шаблоны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования . Эддисон Уэсли. стр. 257 и далее . ISBN 0-201-63361-2 .
- ^ «Шаблон проектирования «Итератор» — проблема, решение и применимость» . w3sDesign.com . Проверено 12 августа 2017 г.
- ^ Банда четырех
- ^ «Шаблон проектирования «Итератор. Структура и сотрудничество» . w3sDesign.com . Проверено 12 августа 2017 г.
- ^ Бьерн Страуструп (2014). Программирование: принципы и практика с использованием C ++ (2-е изд.). Эддисон Уэсли. стр. 729 и далее. ISBN 978-0-321-99278-9 .
Внешние ссылки
[ редактировать ]