Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 [ 80 ] 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239

Таблица 7.1 (продолжение)

Категория

Возможности

Поддержка

Прямой итератор

Двунаправленный итератор

Итератор

Чтение и запись в прямом направлении

Чтение и запись в прямом и обратном направлениях

Чтение и запись

произвольного доступа с произвольным доступом

Списки, множества, мультимножества, отображения, мультиотображения

Вектор, дек, строка, массив

Итератор ввода

Итератор вывода

Прямой итератор

Двустороиний итератор

Итератор произвольного доступа

Рис. 7.1. Категории итераторов

Итераторы ввода

Итератор ввода перемещается только вперед и поддерживает только чтение (то есть возвращает значения элементов в порядке их перебора). В табл. 12 перечислены операции итераторов ввода.

Таблица 7.2. Операции итераторов ввода

Выражение

Описание

*iter

lter-> member

++lter

iter++

iterl Iter2 Iterl Ы iter2 TYPE(iter)

Обращение к элементу

Обращение к переменной или функции элемента Смещение вперед (возвращает новую позицию) Смещение вперед (возвращвет старую позицию) Проверка двух итераторов на равенство Проверка двух итераторов на неравенство Копирование итератора (копирующий конструктор)

Итератор ввода читает элементы только один раз. Если скопировать итератор ввода и выполнить <1тение через оригинал и копию, вы можете получить разные значения.



Практически любой итератор обладает базовыми возможностями итераторов ввода, но большинство итераторов способно на большее. Типичным примером «чистого» итератора ввода является итератор, читающий данные из стандартного входного потока данных (обычно с клавиатуры). Одно значение не может быть прочитано дважды. После чтения слова из входного потока данных при следующем обращении будет получено другое слово.

Два итератора ввода считаются равными, если они находятся в одной позиции. Однако, как упоминалось выше, это не означает, что при следующем чтении они вернут одно и то же значение.

По возможности используйте префиксный оператор перемещения итератора вместо постфиксного, потому что он может работать более эффективно. Дело в том, что префиксной форме не нужно возвращать старое значение, которое должно храниться во временном объекте. Следовательно, для итератора pes (и любого абстрактного типа данных) рекомендуется использовать префиксный оператор:

++POS правильно и быстро

Префиксный оператор работает быстрее постфиксного:

POS++ Правильно, но не быстро

Это утверждение относится и к оператору - (для тех итераторов, для которых он определен, - итераторы ввода его не поддерживают).

Итераторы вывода

Итераторы вывода составляют пару с итераторами ввода. Они тоже перемещаются только вперед, но выполняют запись. Таким образом, присваивание новых значений выполняется только для отдельных элементов. Итератор вывода не может использоваться для повторного перебора интервала. Запись производится в некую абстрактную «черную дыру»; если вы повторно записываете данные в той же позиции в исходную «черную дыру», ничто не гарантирует, что они будзгг записаны поверх предыдущих данных. В табл. 7.3 перечислены операции итераторов вывода.

Таблица 7.3. Операции итераторов вывода Выражение Описание

*lter=value Записывает value в позицию, определяемую итератором

++iter Смещение вперед (возвращает новую позицию)

lter++ Смещение вперед (возвращает старую позицию)

TYPE(iter) Копирование итератора (копирующий конструктор)

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

На практике итераторы обычно поддерживают как чтение, так и запись. Абсолютное большинство итераторов обладает свойствами итераторов вывода (как



и итераторов ввода). Типичным примером «чистого» итератора вывода служит итератор для записи в стандартный выходной поток данных (например, на экран или на принтер). Если ргспользовать два итератора вывода для записи на экран, то второе слово будет выводиться после первого, а не поверх него. Другой типичный пример итератора вывода - итератор вставки, предназначенный для занесения новых значений в контейнер. Операция присваивания приводит к тому, что в контейнер вставляется новый элемент. При последующей записи второе значение не стирает первое, а просто вставляется отдельно от него. Итераторы вставки рассматриваются на с, 275.

Прямые итераторы

прямые итераторы представляют собой комбинацию итераторов ввода и вывода. Они обладают всеми свойствами итераторов ввода и большинством свойств итераторов вывода. Операции прямых итераторов перечислены в табл. 7.4.

Таблица 7.4. Операции прямых итераторов

Выражение

Описание

*iter

Обращение к элементу

iter->member

Обращение к переменной или функции элемента

++iter

Смещение вперед (возвращает новую позицию)

iter++

Смещение вперед (возвращает старую позицию)

iterl == iter2

Проверка двух итераторов на равенство

iterl != iter2

Проверка двух итераторов на неравенство

TYPEQ

Копирование итератора (конструктор по умолчанию)

TYPE(iter)

Копирование итератора (копирующий конструктор)

iirl = iter2

Присваивание итератора

В отличие от итераторов ввода и вывода прямые итераторы могут ссылаться на один и тот же элемент коллекции и обрабатывать его по несколько раз.

Возможна, вас интересует, почему прямой итератор не обладает всеми свойствами итератора вывода. Существует одно важное ограничение, из-за которого код, действительный для итераторов вывода, оказывается недействительным для прямых итераторов.

О Итераторы вывода позво.аяют записывать данные без проверки конца последовательности. Более того, вы даже не можете сравнить итератор вывода с конечным итератором, потому что итераторы вывода не поддерживают операцию сравнения. Следователыто, для итератора вывода pos следующий цикл правилен, а для прямого итератора -- нет:

ОК для итераторов вывода ОШИБКА для прямых итераторов winile (true) {



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 [ 80 ] 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239