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

Тут можно читать онлайн Скотт Мейерс - Эффективное использование STL - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство Питер, год 2002. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Эффективное использование STL
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2002
  • Город:
    СПб.
  • ISBN:
    ISBN 5-94723-382-7
  • Рейтинг:
    4/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Скотт Мейерс - Эффективное использование STL краткое содержание

Эффективное использование STL - описание и краткое содержание, автор Скотт Мейерс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

В этой книге известный автор Скотт Мейерс раскрывает секреты настоящих мастеров, позволяющие добиться максимальной эффективности при работе с библиотекой STL.

Во многих книгах описываются возможности STL, но только в этой рассказано о том, как работать с этой библиотекой. Каждый из 50 советов книги подкреплен анализом и убедительными примерами, поэтому читатель не только узнает, как решать ту или иную задачу, но и когда следует выбирать то или иное решение — и почему именно такое.

Эффективное использование STL - читать онлайн бесплатно полную версию (весь текст целиком)

Эффективное использование STL - читать книгу онлайн бесплатно, автор Скотт Мейерс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Новый вариант вызова erase работает, поскольку выражение i++ равно старому значению i, но у него имеется побочный эффект — приращение i. Таким образом, мы передаем старое (не увеличенное) значение i и увеличиваем i перед вызовом erase. Именно это нам и требовалось. Хотя это решение выглядит просто, лишь немногие программисты предложат его с первой попытки.

Пора сделать следующий шаг. Помимо простого удаления всех элементов, для которых badValue возвращает true, мы также хотим регистрировать каждую операцию удаления в журнале.

Для ассоциативных контейнеров задача решается очень просто, поскольку она требует лишь тривиальной модификации созданного цикла:

ofstream logFile;// Файл журнала АссоцКонтейнер с;

for{АссоцКонтейнер: iterator i=c.begin();// Заголовок цикла остается

i!=c.end();) {// без изменений

if (badValue(*i)) {

logFile«"Erasing "« *i «'\n';// Вывод в журнал

c.erase(i++):// Удаление

}

else ++i:

}

На этот раз хлопоты возникают с vecto r, string и deque. Использовать идиому erase/remove не удается, поскольку erase или remove_if нельзя заставить вывести данные в журнал. Более того, вариант с циклом fo r, только что продемонстрированный для ассоциативных контейнеров, тоже не подходит, поскольку для контейнеров vecto r, string и deque он приведет к непредсказуемым последствиям. Вспомните, что для этих контейнеров в результате вызова erase становятся недействительными все итераторы, указывающие на удаляемый элемент. Кроме того, недействительными становятся все итераторы после удаляемого элемента, в нашем примере — все итераторы после i. Конструкции вида i++, ++i и т. д. невозможны, поскольку ни один из полученных итераторов не будет действительным.

Следовательно, с vecto r, string и deque нужно действовать иначе. Мы должны воспользоваться возвращаемым значением erase, которое содержит именно то, что нам требуется — действительный итератор, который указывает на элемент, следующий за удаленным. Иначе говоря, программа выглядит примерно так:

for (ПослКонтейнер: :iterator=cbegin(); i !=cend();){

if (badValue(*i)) {

logFile«"Erasing "«*i«'\n';

i=c.erase());// Сохраняем действительный итератор i,

}// для чего ему присваивается значение,

else ++i;// возвращаемое функцией erase

}

Такое решение превосходно работает, но только для стандартных последовательных контейнеров. По весьма сомнительным причинам (совет 5) функция erase для стандартных ассоциативных контейнеров возвращает void. В этом случае приходится использовать методику с постфиксным приращением итератора, переданного erase. Кстати говоря, подобные различия между последовательными и ассоциативными контейнерами — один из примеров того, почему контейнерно-независимый код обычно считается нежелательным (совет 2).

Какое из этих решений лучше подойдет для контейнера list? Оказывается, в отношении перебора и удаления list может интерпретироваться как vector / string/deque или как ассоциативный контейнер — годятся оба способа. Обычно выбирается первый вариант, поскольку list, как и vector/string/deque, принадлежит к числу последовательных контейнеров. С точки зрения опытного программиста STL программа, в которой перебор и удаление из list производятся по правилам ассоциативных контейнеров, выглядит странно.

Подводя итог всему, о чем рассказывалось в этом совете, мы приходим к следующим заключениям.

Удаление всех объектов с заданным значением:

•контейнеры vector, string и deque: используйте идиому erase/remove;

•контейнер list: используйте list::remove;

•стандартный ассоциативный контейнер: используйте функцию erase.

Удаление всех объектов, соответствующих заданному предикату:

•контейнер vector, string и deque: используйте идиому erase/remove_if;

•контейнер list: используйте list:: remove_if;

•стандартный ассоциативный контейнер: используйте remove_copy_if/swap или напишите цикл перебора элементов контейнера, но не забудьте о постфиксном приращении итератора, передаваемого при вызове erase.

Дополнительные операции в цикле (кроме удаления объектов):

•стандартный последовательный контейнер: напишите цикл перебора элементов, но не забывайте обновлять итератор значением, возвращаемым erase при каждом вызове;

•стандартный ассоциативный контейнер: напишите цикл перебора элементов с постфиксным приращением итератора, передаваемого при вызове erase.

Как видите, эффективное удаление элементов контейнера не сводится к простому вызову erase. Правильный подход зависит от того, по какому принципу отбираются удаляемые элементы, в каком контейнере они хранятся и какие дополнительные операции требуется выполнить при удалении. Действуйте осторожно и следуйте рекомендациям данного совета, и все будет нормально. Невнимательность обернется неэффективной работой или непредсказуемым поведением программы.

Совет 10. Помните о правилах и ограничениях распределителей памяти

Распределители памяти первоначально разрабатывались как абстракция для моделей памяти, позволяющих разработчикам библиотек игнорировать различия между near- и far-указателями в некоторых 16-разрядных операционных системах (например, DOS и ее зловредных потомках), однако эта попытка провалилась. Распределители также должны были упростить разработку объектных диспетчеров памяти, но вскоре выяснилось, что такой подход снижает эффективность работы некоторых компонентов STL. Чтобы избежать снижения быстродействия. Комитет по стандартизации С++ включил в Стандарт положение, которое практически выхолостило объектные распределители памяти, но одновременно выражало надежду, что от этой операции их потенциальные возможности не пострадают.

Но это еще не все. Распределители памяти STL, как и operator new с operator new[ ], отвечают за выделение (и освобождение) физической памяти, однако их клиентский интерфейс имеет мало общего с клиентским интерфейсом operator new, operator new[ ] и даже malloc. Наконец, большинство стандартных контейнеров никогда не запрашивает память у своих распределителей. Еще раз подчеркиваю — никогда. В результате распределители производят довольно странное впечатление.

Впрочем, это не их вина, и, конечно же, из этого факта вовсе не следует делать вывод о бесполезности распределителей. Тем не менее, прежде чем описывать области применения распределителей (эта тема рассматривается в совете 11), я должен объяснить, для чего они не подходят. Существует целый ряд задач, которые только на первый взгляд могут решаться при помощи распределителей. Прежде чем вступать в игру, желательно изучить границы игрового поля, в противном случае вы наверняка упадете и получите травму. Кроме того, из-за экзотических особенностей распределителей сам процесс обобщения выглядит весьма поучительным и занимательным. По крайней мере, я на это надеюсь.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Скотт Мейерс читать все книги автора по порядку

Скотт Мейерс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Эффективное использование STL отзывы


Отзывы читателей о книге Эффективное использование STL, автор: Скотт Мейерс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x