C++: библиотека программиста



Download 1,95 Mb.
Pdf ko'rish
bet71/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   67   68   69   70   71   72   73   74   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
119 
перемещаются в коллекцию, а итератор применяется только для хранения служебной информации этих 
функций. Базовый итератор и цикл итерации выглядят так: 
class Iterator
class Collection { 
public: 
Iterator* 
Iterate(); 
// 
Возвращает пассивный итератор 
bool 
More(Iterator*); 
Foo* 
Next(Iterator*); 
}; 
Iterator* iter = collection->Iterate(); 
while (collection->More(iter)) 
f(collection->Next(iter)); 
Такие итераторы называются пассивными, поскольку сами по себе они не выполняют никаких 
действий и предназначены лишь для хранения служебной информации. 
Что лучше? 
Выбор между активными и пассивными итераторами в основном зависит от стиля, но я предпочитаю 
активные итераторы по нескольким причинам: 
• 
Законченный класс итератора проще использовать повторно, чем пару функций большого 
класса. 
• 
Рано или поздно вам захочется предоставить несколько разных способов перебора содержимого 
коллекции. Один и тот же общий интерфейс класса 
Iterator
подойдет для любого способа, а в 
форме функций класса для каждого типа перебора вам придется создавать пару новых функций. 
• 
Пассивные итераторы не имеют открытого интерфейса, однако клиентские объекты видят их 
через адреса. Это выглядит довольно странно. 
• 
При равенстве всех остальных показателей я обычно предпочитаю активные итераторы, 
поскольку они обеспечивают лучшую инкапсуляцию. 
В коммерческих библиотеках классов можно встретить хорошие примеры обеих форм. В вопросе об 
активных и пассивных итераторах отражается общий спор об активных и пассивных объектах, поэтому 
в первую очередь следует учитывать собственные приемы проектирования. 
Убогие, но распространенные варианты 
Вряд ли вы встретите в коммерческих библиотеках классов итераторы именно в таком виде. У каждого 
находится свой подход к этой теме. Ниже перечислены некоторые варианты, которые часто 
встречаются в странствиях по С++, с краткими комментариями по поводу их достоинств и недостатков. 
Мономорфные активные итераторы вне области действия 
Даже жалко расходовать замечательный термин на такую простую концепцию. Итераторы называются 
мономорфными, поскольку в них не используются виртуальные функции, и находятся вне области 
действия, поскольку они не объявляются вложенными в коллекцию. 
class Collection { ... }; 
class CollectionIterator { 
private: 
Collection* 
coll; 
public: 
CollectionIterator(Collection* 
coll); 
bool 
More(); 
Foo* 
Next(); 
}; 


 120 
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()
, обратно к 
правильному типу — и горе ему, если он что-нибудь напутает. Шаблоны изобретались именно для этой 
цели, так что теперь подобный бред уже нельзя оправдать. 
Лучшие варианты 
Начиная с этого места, я буду говорить об активных итераторах, однако все сказанное в равной мере 
относится и к пассивным итераторам. Некоторые разновидности итераторов сильно зависят от 
характеристик коллекции, но другие обладают большей универсальностью. Перечисляю их, не 
придерживаясь какого-то определенного порядка. 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   67   68   69   70   71   72   73   74   ...   144




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish