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

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

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

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

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

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

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

своих данных дополнительные ограничения, и при передаче вектора функции
API, изменяющей его содержимое, вы должны проследить за тем, чтобы эти
ограничения не были нарушены. Например, как объясняется в совете 23,
сортируемые векторы часто могут рассматриваться в качестве разумной
альтернативы для ассоциативных контейнеров, но при этом содержимое таких
векторов должно оставаться правильно отсортированным. При передаче
сортируемого вектора функции, способной изменить его содержимое, вам
придется учитывать, что при возвращении из функции сортировка элементов
может быть нарушена.
Если у вас имеется vector, который должен инициализироваться внутри
функции С, можно воспользоваться структурной совместимостью vector с
массивами и передать функции указатель на блок элементов вектора:
// Функция fillArray получает указатель на массив.
// содержащий не более arraySize чисел типа double.
// и записывает в него данные. Возвращаемое количество записанных //
чисел заведомо не превышает maxNumDoubles. size_t fi11Array(double
*pArray, size_t arraySize):
vector<double> vd(maxNumDoubles); // Создать vector, емкость которого
// равна maxNumDoubles
vd,resize(fillArray(&vd[0],vd.sizeO)): // Заполнить vd вызовом
// функции fillArray. после чего // изменить размер по количеству //
записанных элементов
Данный способ подходит только для vector, поскольку только этот контейнер
заведомо совместим с массивами по структуре памяти. Впрочем, задача
инициализации string функцией С тоже решается достаточно просто. Данные,
возвращаемые функцией, заносятся в vector<char> и затем копируются из
вектора в string:
// Функция получает указатель на массив, содержащий не более // arraySize
символов, и записывает в него данные.
// Возвращаемое количество записанных чисел заведомо не превышает //
maxNumChars
78 Глава 2 • Контейнеры vector и string
size_t fillString(char *pArray. size_t arraySize);
vector<char> vc(maxNumChars); // Создать vector, емкость
которого
// равна maxNumChars size_t charsWritten = fillString(&vc[0].vc.size());
// Заполнить vc
// вызовом fill String string s(vc.begin().vc.beginO+charsWritten): //
Скопировать данные
// из vc в s интервальным // конструктором (совет 5)
Собственно, сам принцип сохранения данных функцией API в vector и их
последующего копирования в нужный контейнер STL работает всегда:
size_t fillArray(double *pArray. size_t arraySize): // См. ранее
vector<double> vd(maxNumDoubles); // Также см. ранее
vd.resize(fillArray(&vd[0].vd.size()):
deque<double> d(vd.beginO.vd.endO); // Копирование в deque
list<double> Kvd.beginO.vd.endO); // Копирование в list
set<double> s(vd.begin(),vd.end()): // Копирование в set
Более того, этот фрагмент подсказывает, как организовать передачу данных
из других контейнеров STL, кроме vector и stri ng, функциям С. Для этого
достаточно скопировать данные контейнера в vector и передать его при
вызове:
void doSomething(const int* pints. size_t numlnts); // Функция С (см.
ранее) set<int> intSet: // Множество, в котором
// хранятся передаваемые // данные
vector<int> vdntSet.begin().intSet.end()): // Скопировать данные
// из set в vector
if (Iv.emptyO) doSomething(&v[0],v.size()): // Передать данные
// функции С
Вообще говоря, данные также можно скопировать в массив и передать их
функции С, но зачем это нужно? Если размер контейнера не известен на
стадии компиляции, память придется выделять динамически, а в совете 13
объясняется, почему вместо динамических массивов следует использовать
vector.
Совет 17. Используйте "фокус с перестановкой" для уменьшения емкости
Предположим, вы пишете программу для нового телешоу "Бешеные деньги".
Информация о потенциальных участниках хранится в векторе:
class Contestant {...}; vector<Contestant> contestants:
При объявлении набора участников заявки сыплются градом, и вектор быстро
заполняется элементами. Но по мере отбора перспективных кандидатов
относительно небольшое количество элементов перемещается в начало вектора
(вероят-
Совет 17 79
но, вызовом partial_sort или partition - см. совет 31), а неудачники
удаляются из вектора (как правило, при помощи интервальной формы erase -
см. совет 5). В результате удаления длина вектора уменьшается, но емкость
остается прежней. Если в какой-то момент времени вектор содержал данные о
100 ООО кандидатов, то его емкость останется равной 100 ООО, даже если
позднее количество элементов уменьшится до 10.
Чтобы вектор не удерживал ненужную память, необходимы средства, которые
бы позволяли сократить емкость от максимальной до используемой в
настоящий момент. Подобное сокращение емкости обычно называется "сжатием
по размеру". Сжатие по размеру легко программируется, однако код - как бы
выразиться поделикатнее? - выглядит недостаточно интуитивно. Давайте
разберемся, как он работает.
Усечение лишней емкости в векторе contestants производится следующим
образом:
vector<Contestant>(contestants).swap(contestants);
Предыдущая << 1 .. 34 35 36 37 38 39 < 40 > 41 42 43 44 45 46 .. 114 >> Следующая