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

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

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

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

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

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

Мейерс С. Эффективное использование STL. Библиотека программиста — Спб.: Питер , 2002. — 224 c.
ISBN 5-94723-382-7
Скачать (прямая ссылка): effektivnoeispolzovaniestlbibliote2002.djvu
Предыдущая << 1 .. 58 59 60 61 62 63 < 64 > 65 66 67 68 69 70 .. 114 >> Следующая

поделаешь.
Совет 30 125
При вставке в контейнеры vector и string для сокращения затрат можно
последовать совету 14 и заранее вызвать reserve. Затраты на сдвиг
элементов при каждой вставке от этого не исчезнут, но по крайней мере вы
избавитесь от необходимости перераспределения памяти контейнера:
vector<int> values: // См. ранее
vector<int> results:
results.reserve(results.size()+values.size()): // Обеспечить
наличие
// в векторе results // емкости для value.sizeO // элементов
transform(values.begin(), values.end(). // To же, что и ранее,
inserter(results.results.begin()+results.size()/2), // но без лишних
trannragrify); // перераспределений памяти
При использовании функции reserve для повышения эффективности серии
вставок всегда помните, что reserve увеличивает только емкость
контейнера, а размер остается неизменным. Даже после вызова reserve при
работе с алгоритмом, который должен включать новые элементы в vector или
string, необходимо использовать итератор вставки (то есть итератор,
возвращаемый при вызове back_ inserter, f ronti nserter или inserter).
Чтобы это стало абсолютно ясно, рассмотрим ошибочный путь повышения
эффективности для примера, приведенного в начале совета (с присоединением
результатов обработки элементов values к results):
vector<int> values: // См. ранее
vector<int> results:
results.reserve(results.size()+values.sizeO): // См. ранее
transform(values.begin().values.end(), // Результаты вызова
results.endO, // transmogrify записываются
transmogrify); // в неинициализированную
// память; последствия // непредсказуемы!
В этом фрагменте transform в блаженном неведении пытается выполнить
присваивание в неинициализированной памяти за последним элементом
results. Обычно подобные попытки приводят к ошибкам времени выполнения,
поскольку операция присваивания имеет смысл лишь для двух объектов, но не
между объектом и двоичным блоком с неизвестным содержимым. Но даже если
зтот код каким-то образом справится с задачей, вектор resul ts не будет
знать о новых "объектах", якобы созданных в его неиспользуемой памяти. С
точки зрения results вектор после вызова transform сохраняет прежний
размер, а его конечный итератор будет указывать на ту же позицию, на
которую он указывал до вызова transform. Мораль? Использование reserve
без итератора вставки приводит к непредсказуемым последствиям внутри
алгоритмов и нарушению целостности данных в контейнере.
126 Глава 5 • Алгоритмы
В правильном решении функция reserve используется в сочетании с
итератором вставки:
vector<int> values; // См. ранее
vector<int> results:
results.reserve(results.size()+values.sizeO); // См. ранее
transform(values.begin(),values.end(), // Результаты вызова
back_inserter(results), // transmogrify записываются
transmogrify); // в конец вектора results
// без лишних перераспределений // памяти
До настоящего момента предполагалось, что алгоритмы (такие как transform)
записывают результаты своей работы в контейнер в виде новых элементов.
Эта ситуация является наиболее распространенной, но иногда новые данные
требуется записать поверх существующих. В таких случаях итератор вставки
не нужен, но вы должны в соответствии с данным советом проследить за тем,
чтобы приемный интервал был достаточно велик.
Допустим, вызов transform должен записывать результаты в results поверх
существующих элементов. Если количество элементов в resul ts не меньше их
количества в val ues, задача решается просто. В противном случае придется
либо воспользоваться функцией resize для приведения results к нужному
размеру:
vector<int> results:
if (results.size()<values.size()){ // Убедиться в тон, что размер
results.resize(values.sizeO); // results по крайней мере
} // не меньше размера values
transform(values.begin(),values.end(), // Перезаписать первые
back_inserter(results), // values.sizeO элементов results
transmogrify):
либо очистить resul ts и затем использовать итератор вставки стандартным
способом:
results.clearO; // Удалить из results все элементы
results, reserve (val ues. sizeO): // Зарезервировать память
transform(values.begin().values.end(), // Занести выходные данные
back_inserter(results), // transform в results
transmogrify);
В данном совете было продемонстрировано немало вариаций на заданную тему,
но я надеюсь, что в памяти у вас останется основная мелодия. Каждый раз,
когда вы используете алгоритм, требующий определения приемного интервала,
позаботьтесь о том, чтобы приемный интервал имел достаточные размеры или
автоматически увеличивался во время работы алгоритма. Второй вариант
реализуется при помощи итераторов вставки - таких, как ostream_i terator,
или возвращаемых в результате вызова back_inserter, front_inserter и
inserter. Вот и все,
о чем необходимо помнить.
Совет 31 127
Совет 31. Помните о существовании разных средств сортировки
Когда речь заходит об упорядочении объектов, многим программистам
приходит в голову всего один алгоритм: sort (некоторые вспоминают о
Предыдущая << 1 .. 58 59 60 61 62 63 < 64 > 65 66 67 68 69 70 .. 114 >> Следующая