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

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

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

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

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

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

Мейерс С. Эффективное использование STL. Библиотека программиста — Спб.: Питер , 2002. — 224 c.
ISBN 5-94723-382-7
Скачать (прямая ссылка): effektivnoeispolzovaniestlbibliote2002.djvu
Предыдущая << 1 .. 47 48 49 50 51 52 < 53 > 54 55 56 57 58 59 .. 114 >> Следующая

map<string, int>. Перед нами практически буквальное переложение
комментариев, приведенных ранее, если не считать присутствия функции
keyLess, предназначенной для согласования функций operatorO. Каждая
функция просто сравнивает два ключа, поэтому, чтобы не программировать
одни и те же действия дважды, мы производим проверку в keyLess, а функция
operatorO возвращает полученный результат. Конечно, этот прием упрощает
сопровождение DataCompare, однако у него есть один недостаток: наличие
функций operatorO с разными типами параметров исключает адаптацию
объектов функций (см. совет 40). С этим ничего не поделаешь.
Контейнер тар эмулируется на базе сортированного вектора практически так
же, как и контейнер set. Единственное принципиальное отличие заключается
в том, что в качестве функций сравнения используются объекты DataCompare:
vector<Widget> vd: // Альтернатива для map<string.int>
// Подготовительная фаза: много вставок.
// мало операций поиска
// Функция сравнения // для поиска (форма 2)
// "Настоящая" функция // сравнения
Совет 24 103
sort(vd.begin().vd.end(),DataCompareO): // Конец подготовительной фазы
// (при эмуляции multiset можно // воспользоваться алгоритмом //
stable_sort - см. совет 31) string s: // Объект с искомым значением
// Начало фазы поиска if
(binary_search(vd.begin().vd.end(),s,DataCompare()))... // Поиск
// с применением binary_search
vector<Data>::iterator i =
1ower_bound(vd.begi n(),vd.end().s,
DataCompareO): if (i!=vd.end() && !(i->first<s))".
// Поиск с применением // lower_bound: конструкция // !(i->first<s))
описана // в совете 45
pa i r<vector<Data>::iterator.
vector<Data>::iterator" range = equal_range(vd.begin() .vd.endO ,s,
DataCompareO): if (range, first != range, second)...
// Поиск с применением // equal_range
// Конец фазы поиска,
// начало фазы реорганизации // Начало новой фазы поиска...
sort(vd.begi n(),vd.end(),DataCompa re()):
Как видите, после написания DataCompare все более или менее становится на
свои места. Показанное решение часто быстрее работает и расходует меньше
памяти, чем аналогичная архитектура с настоящим контейнером шар - при
условии, что операции со структурой данных в вашей программе делятся на
фазы, описанные на с. 99. Если подобное деление на фазы не соблюдается,
использование сортированного вектора вместо стандартных ассоциативных
контейнеров почти всегда оборачивается напрасной тратой времени.
Совет 24. Тщательно выбирайте между map::operator[] и map::insert
Допустим, у нас имеется класс Wi dget с конструктором по умолчанию, а
также конструктором и оператором присваивания с операндом типа double:
class Widget { public:
WidgetO;
Wi dget(double wei ght):
WidgetS operator=(double weight);
Предположим, мы хотим создать контейнер map, ассоциирующий int с Widget,
и инициализировать созданное множество конкретными значениями. Все
выглядит очень просто:
map<int.Widget> m;
m[l]=1.50: m[2]=3.67;
104 Глава 3 • Ассоциативные контейнеры
ш[3]=10.5:
ш[4]=45.8;
т[5]=0.0003:
Настолько просто, что легко упустить, что же здесь, собственно,
происходит. А это очень плохо, потому что в действительности происходящее
может заметно ухудшить быстродействие программы.
Функция operator[] контейнеров шар никак не связана с функциями
operator[] контейнеров vector, deque и string, а также со встроенным
оператором [ ], работающим с массивами. Функция шар: :operator[] упрощает
операции "обновления с возможным созданием". Иначе говоря, при наличии
объявления map<K, V> m команда m[k]=v; проверяет, присутствует ли ключ к
в контейнере. Если ключ отсутствует, он добавляется вместе с
ассоциированным значением v. Если ключ уже присутствует, ассоциированное
с ним значение заменяется на v.
Для этого operator [] возвращает ссылку на объект значения,
ассоциированного с ключом к, после чего v присваивается объекту, к
которому относится эта ссылка. При обновлении значения, ассоциированного
с существующим ключом, никаких затруднений не возникает - в контейнере
уже имеется объект, ссылка на который возвращается функцией operator[].
Но при отсутствии ключа к готового объекта, на который можно было бы
вернуть ссылку, не существует. В этом случае объект создается
конструктором по умолчанию, после чего operatorf] возвращает ссылку на
созданный объект.
Вернемся к началу исходного примера:
map<int,Widget> m;
гп[1]=1.5 О.-
Выражение ш[1] представляет собой сокращенную запись для m.operator[](l),
поэтому во второй строке присутствует вызов шар: :operator[]. Функция
должна вернуть ссылку на ассоциированный объект Widget. В данном примере
m еще не содержит ни одного элемента, поэтому элемент с ключом 1 не
существует. Конструктор по умолчанию создает объект Widget, ассоциируемый
с ключом 1, и возвращает ссылку на этот объект. Наконец, созданному
объекту Widget присваивается значение 1.50.
Иначе говоря, команда
ш[1]=1.50:
функционально эквивалентна следующему фрагменту:
typedef map<int.Widget> intWidgetMap; // Вспомогательное определение типа
Предыдущая << 1 .. 47 48 49 50 51 52 < 53 > 54 55 56 57 58 59 .. 114 >> Следующая