Анимация
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

было бы непрактично. Таким образом, только одноэлементная вставка в ассоциативные контейнеры обеспечивает транзакционнуго безопасность (то есть либо завершается успешно, либо не вносит изменений). Кроме того, гарантируется, что все операции удаления (как одного, так и нескольких элементов) всегда завершаются успешно.

Для списков даже вставка нескольких элементов обладает транзакционной безопасностью. Более того, любые операции со списками, кроме rernove(), remove if(), rnerge(), sort() и uniqueQ, либо завершаются успешно, либо не вносят изменений. Для некоторых из перечисленных операций стандартная библиотека С++ предоставляет условные гарантии (см. с. 180). Отсюда можно сделать вывод: если вам требуется контейнер, обладающий транзакционной безопасностью, выбирайте список.

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

Более подробный перечень всех контейнерных операций, обеспечивающих в отношении исключений более твердые гарантии, приведен на с. 254.

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

Если вам понадобится контейнер с полными гарантиями транзакционной безопасности, используйте либо список (без вызова функций sort() и unique()), либо ассоциативный контейнер (без вызова многоэлементных операций вставки). Тогда вам не придется создавать копии данных перед модификацией, чтобы предотвратить возможную потерю данных. Копирование контейнеров иногда обходится очень дорого.

Если вы не используете узловой контейнер, но нуждаетесь в полноценной тюддержке транзакционной безопасности, для всех критических оаераций придется делать промежуточные копии данных. Например, следующая функция обеспечивает почти безопасную вставку значения в заданную позицию произвольного контейнера:

template <class Т. class Cont, class Iter>

void Insert CCont& coll. const IterS pos, const T& value)

Cont tmp(coll); Копирование контейнера со всеми элементами

tmp.insertCpos.value); Модификация копии

coll.swap(tmp); Использование копии (если модификация

} выполнена без исключений)



«Почти» означает, что эта функция не идеальна. Дело в том, что функция swapO тоже может генерировать псключсннс, если оно имеет место в критерии сравнения ассоциативного контейнера. Как видите, безупречная обработка исключений - дело весьма непростое.

Расширение STL

Библиотека STL проектировалась с расчетом на возможность расширения практически в любом направлении. Программист может создавать и использовать собственные контейнеры, итераторы, алгоритмы и объекты функций, удовлетво-ряюшие определенным требованиям. Кроме того, в стандартной библиотеке С-Ы-не поддерживаются некоторые полезные возможности, поскольку в какой-то момент комитет по стандартизации был вынужден прекратить прием новых предложений и сосредоточиться на приведении в порядок того, что есть; иначе работа продолжалась бы до бесконечности.

Самое заметное упущение в STL - отсутствие такого типа контейнера, как хэш-таблица. Просто предложение о включении хэш-таблиц в стандартную библиотеку С++ поступило слишком поздно. Тем не менее весьма вероятно, что новые версии стандарта будут содержать те или иные формы хэшей. Большинство реализаций библиотеки С++ уже содержат хэш-контейнеры, но, к сожалению, все они реализованы по-разному. За дополнительной информацией обращайтесь на с. 225.

Среди других полезных расширений стоит отметить дополнительные объекты функций (см. с. 313), итераторы (см. с. 291), контейнеры (см. с. 221) и алгоритмы (см. с. 289).




Контейнеры STL

в этой главе, которая продолжает тему, начатую в главе 5, приведены подробные описания контейнеров STL. Начинается она с обзора общих возможностей и операций всех контейнерных классов, после чего каждый контейнерный класс рассматривается в отдельности. В каждом случае представлены внутренние структуры данных, основные операции контейнера и их эффективность. Также показано, как использовать различные операции контейнера; нетривиальные случаи поясняются примерами. Кроме того, типичными примерами использования контейнеров завершаются все разделы, посвященные конкретным контейнерам. Далее обсуждается интересный вопрос: в каких ситуациях следует применять тот нли иной контейнер? Сравнительный анализ общих возможностей, достоинств и недостатков разных типов контейнеров поможет подобрать оптимальный контейнер для конкретной ситуации. Глава завершается подробным описанием всех членов контейнерных классов. Это описантге было задумано как своего рода справочное руководство. В нем перечислены все нюансы интерфейса контейнера и приводятся точные сигнатуры всех контейнерных операций. Там, где это уместно, приводятся перекрестные ссылки на похожие или вспомогательные алгоритмы.

Стандартная библиотека С++ также содержит ряд специализированных кон-чейиерных классов - это так называемые контейпермые адаптеры (стек, очередь, приоритетная очередь), битовые поля и массивы, зиачепий. Все эти контейнеры обладают специальным интерфейсом, не соответствующим общим требованиям к контейнерам STL, поэтому они рассматриваются отдельно. Контейнерные адаптеры и битовые поля рассматриваются в главе 10. Массивы значений описаны на с. 525.

Общие возможности и операции Общие возможности контейнеров

Здесь сформулированы общие возможности всех контейнерных классов STL. В большинстве случаев речь идет о требованиях, которые должны выполняться всеми контейнерами STL. Ниже перечислены три основных требования.

Традиционно контейнерные адаптеры считаются частью STL. Тем не менее на концептуальном уропне адаптер!]] не входят и иерархию STL, а <;все[-о лишь» используют ее.



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