|
Активные итераторы Активным называется итератор, который сам перемещается к следующей позиции. class Collection { public: class Iterator { public: bool More(); Foo* Next(); }; Collection::Iterator* Iterate(); // Создает итератор }; Collection::Iterator* iter = collection->Iterator(); while (iter.More()) f(iter.Next()); Как правило, итераторы относятся к конкретным коллекциям; по этой причине они часто объявляются в виде вложенных классов. Функция Моrе() возвращает true, если в коллекции имеется следующий элемент в порядке перебора, и false - в противном случае. Функция Next() возвращает следующий элемент и перемещает итератор к следующей позиции. Если вы готовы пойти на дополнительные расходы, связанные с виртуальными функциями, итератор также можно реализовать в виде универсального шаблона, работающего с любыми коллекциями. template <class Type> class Iterator { // Подходит для любых коллекций и типов public: virtual bool More() = 0; virtual Type* Next() = 0; }; Каждая коллекция может реализовать итератор заново в производном классе, а клиенты по-прежнему понятия не имеют о том, как происходит перебор и даже какой класс находится по другую сторону забора. К сожалению, в некоторых коллекциях необходимо предоставить средства, не поддерживаемые коллекциями других типов (например, ограничение перебираемого диапазона), поэтому такой шаблон не настолько универсален, как кажется с первого взгляда. Я называю такие итераторы активными, поскольку для выполнения всей основной работы вызываются их функции. Ситуация выглядит так, словно кто-то отломил кусок коллекции и вставил его в переносимый маленький объект. После конструирования такой объект сам знает, что ему делать дальше. |
Copyright 2005. Климов Александр. All Right Reserved.