С++ - язык, который изучается постепенно.Убогие,но распространенные варианты
                   Справочники Всё для создания сайта

Ссылки


Home
Бизнес
Справочники
Советы







Материалы книги получены с http://www.itlibitum.ru/

Убогие, но распространенные варианты

Вряд ли вы встретите в коммерческих библиотеках классов итераторы именно в таком виде. У каждого находится свой подход к этой теме. Ниже перечислены некоторые варианты, которые часто встречаются в странствиях по С++, с краткими комментариями по поводу их достоинств и недостатков.

Мономорфные активные итераторы вне области действия

Даже жалко расходовать замечательный термин на такую простую концепцию. Итераторы называются мономорфными, поскольку в них не используются виртуальные функции, и находятся вне области действия, поскольку они не объявляются вложенными в коллекцию.

class Collection { ... };

class CollectionIterator {

private:

Collection* coll;

public:

CollectionIterator(Collection* coll);

bool More();

Foo* Next();

};

CollectionIterator iter(collection); // Создать итератор

while (iter.More())

f(iter.Next());

Просто удивительно, что всего несколько строк программы порождает столько проблем:

При использовании класса, производного от Collection, каждый клиент должен знать, какие

новые классы итераторов должны использоваться вместо старого CollectionIterator.

Переменные класса итератора видны всем и каждому. Даже если они не составляют

государственной тайны, весь клиентский код придется перекомпилировать каждый раз, когда

вам захочется изменить реализацию итератора.

Занесение итераторов в стек противоречит некоторым стратегиям многопоточности,

рассматриваемым в следующей главе.

Многократное использование такого кода - задача мерзкая.

Учитывая все это, будет намного, намного лучше попросить класс коллекции: «Пожалуйста, сэр, сделайте мне итератор» вместо того, чтобы самому создавать его в стеке. Невзирая на все проблемы, этот тип итераторов часто встречается в коммерческих библиотеках классов.

Пассивные итераторы типа void*

Самая распространенная вариация на тему пассивных итераторов - не возиться с предварительным объявлением класса итератора, а обмануть клиентов и внушить им, что на самом деле они имеют дело с типом void*. Все это часто маскируется каким-нибудь красивым именем с помощью typedef, но уродливый void* так легко не спрячешь.

typedef void* AprilInParis;

class Collection {

public:

AprilInParis Iterate(); // Возвращает загримированный void*

bool More(AprilInParis&);

Foo* Next(AprilInParis&);

};

Конечно, во внутреннем представлении хранится что-то более разумное, чем void*, поэтому код реализации Collection должен постоянно преобразовывать void* к реальности. Не знаю как вас, но лично меня приводит в ужас одна мысль о том, что клиентский код будет возиться с void* до его преобразования. К тому же отладка такого кода дьявольски сложна, поскольку отладчик знает о том, с чем он имеет дело, ничуть не больше клиента. Красивое название итератора не скроет изначального уродства такого подхода.

Нетипизированные значения функции Next()

Многие классы итераторов пишутся в обобщенной форме для типа void* или какого-то абстрактного базового класса. Клиент должен сам приводить значение, возвращаемое функцией Next(), обратно к правильному типу - и горе ему, если он что-нибудь напутает. Шаблоны изобретались именно для этой цели, так что теперь подобный бред уже нельзя оправдать.


Назад    Содержание    Далее    

Home  Создание сайтов  Учебник по записи CD  Справочник Web дизайнера Самоучитель IE PHP и MySQL Компьютерные сети С++ E-mail me

Copyright 2007. Климов Александр. All Right Reserved.
Hosted by uCoz