Книги
чёрным по белому
Главное меню
Главная О нас Добавить материал Поиск по сайту Карта книг Карта сайта
Книги
Археология Архитектура Бизнес Биология Ветеринария Военная промышленность География Геология Гороскоп Дизайн Журналы Инженерия Информационные ресурсы Искусство История Компьютерная литература Криптология Кулинария Культура Лингвистика Математика Медицина Менеджмент Металлургия Минералогия Музыка Научная литература Нумизматика Образование Охота Педагогика Политика Промышленные производства Психология Путеводители Религия Рыбалка Садоводство Саморазвитие Семиотика Социология Спорт Столярное дело Строительство Техника Туризм Фантастика Физика Футурология Химия Художественная литература Экология Экономика Электроника Энергетика Этика Юриспруденция
Новые книги
Цуканов Б.И. "Время в психике человека" (Медицина)

Суворов С. "Танк Т-64. Первенец танков 2-го поколения " (Военная промышленность)

Нестеров В.А. "Основы проэктирования ракет класса воздух- воздух и авиационных катапульных установок для них" (Военная промышленность)

Фогль Б. "101 вопрос, который задала бы ваша кошка своему ветеринару если бы умела говорить" (Ветеринария)

Яблоков Н.П. "Криминалистика" (Юриспруденция)
Реклама

Эффективное использование STL. Библиотека программиста - Мейерс С.

Мейерс С. Эффективное использование STL. Библиотека программиста — Спб.: Питер , 2002. — 224 c.
ISBN 5-94723-382-7
Скачать (прямая ссылка): effektivnoeispolzovaniestlbibliote2002.djvu
Предыдущая << 1 .. 30 31 32 33 34 35 < 36 > 37 38 39 40 41 42 .. 114 >> Следующая

обычно менее надежно, чем "фокус с перестановкой", описанный в совете 17.
70 Глава 2 • Контейнеры vector и string
Из краткого описания функций становится ясно, что перераспределение
(выделение и освобождение блоков памяти, копирование и уничтожение
объектов, обновление недействительных итераторов, указателей и ссылок)
происходит каждый раз, когда при вставке нового элемента текущая емкость
контейнера оказывается недостаточной. Таким образом, для предотвращения
лишних затрат следует установить достаточно большую емкость контейнера
функцией reserve, причем сделать это нужно как можно раньше - желательно
сразу же после конструирования контейнера.
Предположим, вы хотите создать vector<int> с числами из интервала 1-1000.
Без использования reserve это делалось бы примерно так:
vector<int> v;
for (int i=l: i<=1000: ++i) v.push_back(i):
В большинстве реализаций STL при выполнении этого фрагмента произойдет от
2 до 10 расширений контейнера. Кстати, число 10 объясняется очень просто.
Вспомните, что при каждом перераспределении емкость vector обычно
увеличивается вдвое, а 1000 примерно равно 210.
vector'd nt> v:
v.reserve(lOOO):
for (int i-1: i<=1000: ++i) v.push_back(i);
В этом случае количество расширений будет равно нулю.
Взаимосвязь между size и capacity позволяет узнать, когда вставка в
vector или string приведет к расширению контейнера. В свою очередь, это
позволяет предсказать, когда вставка приведет к недействительности
итераторов, указателей и ссылок в контейнере. Пример:
string s;
if (s.sizeO < s.capacityO) { s.push_back('x');
}
В этом фрагменте вызов push_back не может привести к появлению
недействительных итераторов, указателей и ссылок, поскольку емкость
string заведомо больше текущего размера. Если бы вместо push_back
выполнялась вставка в произвольной позиции строки функцией insert, это
также гарантировало бы отсутствие перераспределений памяти, но в
соответствии с обычными правилами действительности итераторов для вставки
в string все итераторы/указатели/ссылки от точки вставки до конца строки
стали бы недействительными.
Вернемся к основной теме настоящего совета. Существуют два основных
способа применения функции reserve для предотвращения нежелательного
перераспределения памяти. Первый способ используется в ситуации, когда
известно точное или приблизительное количество элементов в контейнере. В
этом случае, как в приведенном выше примере с vector, нужный объем памяти
просто резервируется заранее. Во втором варианте функция reserve
резервирует максимальный объем памяти, который может понадобиться, а
затем после включения данных в контейнер вся свободная память
освобождается. В усечении свободной памяти нет ниче-
Совет 15 71
го сложного, однако я не буду описывать эту операцию здесь, потому что в
ней используется особый прием, рассмотренный в совете 17.
Совет 15. Помните о различиях в реализации string
Бьерн Страуструп однажды написал статью с интригующим названием "Sixteen
Ways to Stack a Cat" [27], в которой были представлены разные варианты
реализации стеков. Оказывается, по количеству возможных реализаций
контейнеры string не уступают стекам. Конечно, нам, опытным и
квалифицированным программистам, положено презирать "подробности
реализации", но если Эйнштейн был прав, и Бог действительно проявляется в
мелочах... Даже если подробности действительно несущественны, в них все
же желательно разбираться. Только тогда можно быть полностью уверенным в
том, что они действительно несущественны.
Например, сколько памяти занимает объект string? Иначе говоря, чему равен
результат sizeof(string)? Ответ на этот вопрос может быть весьма важным,
особенно если вы внимательно следите за расходами памяти и думаете о
замене низкоуровневого указателя char* объектом string.
Оказывается, результат sizeof(string) неоднозначен - и если вы
действительно следите за расходами памяти, вряд ли этот ответ вас
устроит. Хотя у некоторых реализаций контейнер string по размеру
совпадает с char*, так же часто встречаются реализации, у которой string
занимает в семь раз больше памяти. Чем объясняются подобные различия?
Чтобы понять это, необходимо знать, какие данные и каким образом будут
храниться в объекте string.
Практически каждая реализация stri ng хранит следующую информацию:
• размер строки, то есть количество символов;
• емкость блока памяти, содержащего символы строки (различия между
размером и емкостью описаны в совете 14);
• содержимое строки, то есть символы, непосредственно входящие в
строку.
Кроме того, в контейнере stri ng может храниться:
• копия распределителя памяти. В совете 10 рассказано, почему это
поле не является обязательным. Там же описаны странные правила, по
которым работают распределители памяти.
Реализации stri ng, основанные на подсчете ссылок, также содержат:
• счетчик ссылок для текущего содержимого.
В разных реализациях string эти данные хранятся по-разному. Для
наглядности мы рассмотрим структуры данных, используемые в четырех
Предыдущая << 1 .. 30 31 32 33 34 35 < 36 > 37 38 39 40 41 42 .. 114 >> Следующая