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


Авторские права

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

Здесь можно скачать бесплатно "Скотт Мейерс - Эффективное использование STL" в формате fb2, epub, txt, doc, pdf. Жанр: Программирование, издательство Питер, год 2002. Так же Вы можете читать книгу онлайн без регистрации и SMS на сайте LibFox.Ru (ЛибФокс) или прочесть описание и ознакомиться с отзывами.
Скотт Мейерс - Эффективное использование STL
Рейтинг:
Название:
Эффективное использование STL
Издательство:
Питер
Год:
2002
ISBN:
ISBN 5-94723-382-7
Скачать:

99Пожалуйста дождитесь своей очереди, идёт подготовка вашей ссылки для скачивания...

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.

Вы автор?
Жалоба
Все книги на сайте размещаются его пользователями. Приносим свои глубочайшие извинения, если Ваша книга была опубликована без Вашего на то согласия.
Напишите нам, и мы в срочном порядке примем меры.

Как получить книгу?
Оплатили, но не знаете что делать дальше? Инструкция.

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

Описание и краткое содержание "Эффективное использование STL" читать бесплатно онлайн.



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

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






Более эффективное решение основано на использовании неприметного итератора istreambuf_iterator. Итераторы istreambuf_iterator работают аналогично istream_iterator, но если объекты istream_iterator<char> читают отдельные символы из входного потока оператором <<, то объекты streambuf_iterator обращаются прямо к буферу потока и непосредственно читают следующий символ (выражаясь точнее, объект streambuf_iterator<char> читает следующий символ из входного потока s вызовом s.rdbuf ()->sgetc()).

Перейти на использование istreambuf_iiterator при чтении файла так просто, что даже программист Visual Basic сделает это со второй попытки:

ifstream inputFile("interestingData.txt");

string fileData(istreambuf_iterator<char>(inputFile)). istreambuf_iterator<char>0);

На этот раз сбрасывать флаг skpws не нужно, итераторы streambuf_iterator никогда не пропускают символы при вводе и просто возвращают следующий символ из буфера.

По сравнению с istream_iterator это происходит относительно быстро. В проведенных мною простейших тестах выигрыш по скорости достигал 40%, хотя в вашем случае цифры могут быть другими. Не удивляйтесь, если быстродействие будет расти со временем; итераторы istreambuf_iterator населяют один из заброшенных уголков STL, и авторы реализаций еще недостаточно позаботились об их оптимизации. Например, в моих примитивных тестах итераторы istreambuf_iterator одной из реализаций работали всего на 5% быстрее, чем istream_iterator. В таких реализациях остается широкий простор для оптимизации i streambuf_iterator.

Если вы планируете читать из потока по одному символу, не нуждаетесь в средствах форматирования ввода и следите за эффективностью выполняемых операций, три лишних символа на итератор — не такая уж дорогая цена за заметный рост быстродействия. При неформатном посимвольном вводе всегда рассматривайте возможность применения sreambuf_iterator.

Раз уж речь зашла о буферизованных итераторах, следует упомянуть и об использовании osreambuf_iterator при неформатном посимвольном выводе. По сравнению с ostream_iterator итераторы ostream_bufiterator обладают меньшими затратами (при меньших возможностях), поэтому обычно они превосходят их по эффективности.

Алгоритмы

В начале главы 1 я упоминал о том, что львиная доля репутации STL связана с контейнерами, и это вполне объяснимо. Контейнеры обладают массой достоинств и упрощают повседневную работу бесчисленных программистов С++. Но и алгоритмы STL тоже по-своему замечательны и в той же степени облегчают бремя разработчика. Существует более 100 алгоритмов, и встречается мнение, что они предо-ставляют программисту более гибкий инструментарий по сравнению с контейнерами (которых всего-то восемь!). Возможно, недостаточное применение алгоритмов отчасти и объясняется их количеством. Разобраться в восьми типах контейнеров проще, чем запомнить имена и предназначение многочисленных алгоритмов.

В этой главе я постараюсь решить две основные задачи. Во-первых, я представлю некоторые малоизвестные алгоритмы и покажу, как с их помощью упростить себе жизнь. Не беспокойтесь, вам не придется запоминать длинные списки имен. Алгоритмы, представленные в этой главе, предназначены для решения повседневных задач — сравнение строк без учета регистра символов, эффективный поиск n объектов, в наибольшей степени соответствующих заданному критерию, обобщение характеристик всех объектов в заданном интервале и имитация copy_if (алгоритм из исходной реализации HP STL, исключенный в процессе стандартизации).

Во-вторых, я научу вас избегать стандартных ошибок, возникающих при работе с алгоритмами. Например, при вызове алгоритма remove и его родственников remove_if и unique необходимо точно знать, что эти алгоритмы делают (и чего они не делают). Данное правило особенно актуально при вызове remove для интервала, содержащего указатели. Многие алгоритмы работают только с отсортированными интервалами, и программист должен понимать, что это за алгоритмы и почему для них установлено подобное ограничение. Наконец, одна из наиболее распространенных ошибок, допускаемых при работе с алгоритмами, заключается в том, что программист предлагает алгоритму записать результаты своей работы в несуществующую область памяти. Я покажу, как это происходит и как предотвратить эту ошибку.

Возможно, к концу главы вы и не будете относиться к алгоритмам с тем же энтузиазмом, с которым обычно относятся к контейнерам, но по крайней мере будете чаще применять их в своей работе.

Совет 30. Следите за тем, чтобы приемный интервал имел достаточный размер

Контейнеры STL автоматически увеличиваются с добавлением новых объектов (функциями insert, push_front, push_back и т. д.). Автоматическое изменение размеров чрезвычайно удобно, и у многих программистов создается ложное впечатление, что контейнер сам обо всем позаботится и им никогда не придется следить за наличием свободного места. Если бы так!

Проблемы возникают в ситуации, когда программист думает о вставке объектов в контейнер, но не сообщает о своих мыслях STL. Типичный пример:

int transmogrify(int х); // Функция вычисляет некое новое значение

// по переданному параметру х

vector<int> values;

… // Заполнение вектора values данными

vector<int> results;// Применить transmogrify к каждому объекту

transform(values.begin(), // вектора values и присоединить возвращаемые

values.end(). // значения к results.

results.end. // Фрагмент содержит ошибку!

transmogrify);

В приведенном примере алгоритм transform получает информацию о том, что приемный интервал начинается с results.end. С этой позиции он и начинает вывод значений, полученных в результате вызова transmogrify для каждого элемента values. Как и все алгоритмы, использующие приемный интервал, transform записывает свои результаты, присваивая значения элементам заданного интервала. Таким образом, transform вызовет transmogrify для values[0] и присвоит результат *results.end(). Затем функция transmogrify вызывается для values[l] с присваиванием результата *(results.end()+1). Происходит катастрофа, поскольку в позиции *results.end() (и тем более в *(results.end()+1) ) не существует объекта! Вызов transform некорректен из-за попытки присвоить значение несуществующему объекту (в совете 50 объясняется, как отладочная реализация STL позволит обнаружить эту проблему на стадии выполнения).

Допуская подобную ошибку, программист почти всегда рассчитывает на то, что результаты вызова алгоритма будут вставлены в приемный контейнер вызовом insert. Если вы хотите, чтобы это произошло, так и скажите. В конце концов, STL — всего лишь библиотека, и читать мысли ей не положено. В нашем примере задача решается построением итератора, определяющего начало приемного интервала, вызовом back_inserter:

vector<int> values:

transform(values.begin(),// Применить transmogrify к каждому

values.end(),// объекту вектора values

back_inserter(results), // и дописать значения в конец results

transmogrify);

При использовании итератора, возвращаемого при вызове back_inserter, вызывается push_back, поэтому back_inserter может использоваться со всеми контейнерами, поддерживающими push_back (то есть со всеми стандартными последовательными контейнерами: vector, string, deque и list). Если вы предпочитаете, чтобы алгоритм вставлял элементы в начало контейнера, Воспользуйтесь front_inserter. Во внутренней реализации front_inserter используется push_front, поэтому front_inserter работает только с контейнерами, поддерживающими эту функцию (то есть deque и list).

… //См. ранее

list<int> results;//Теперь используется

//контейнер list

transform(values.begin(),values.end(). //Результаты вызова transform

front_inserter(results), //вставляются в начало results

transmogrify);//в обратном порядке

Поскольку при использовании front_inserter новые элементы заносятся в начало results функцией push_front, порядок следования объектов в results будет обратным по отношению к порядку соответствующих объектов в values. Это ишь одна из причин, по которым front_inserter используется реже back_inserter. Другая причина заключается в том, что vector не поддерживает push_front, поэтому front_inserter не может использоваться с vector.

Чтобы результаты transform выводились в начале results, но с сохранением порядка следования элементов, достаточно перебрать содержимое values в обратном порядке:

list<int> results;// См. ранее

transform(values.rbegin().values.rend(). // Результаты вызова transform

front_inserter(results), // вставляются в начало results

transmogrify);

// с сохранением исходного порядка

Итак, front_inserter заставляет алгоритмы вставлять результаты своей работы в начало контейнера, a back_inserter обеспечивает вставку в конец контейнера. Вполне логично предположить, что inserter заставляет алгоритм выводить свои результаты с произвольной позиции:

vector<int> values;// См. ранее

vector<int> results;// См. ранее - за исключением того, что

// results на этот раз содержит данные


На Facebook В Твиттере В Instagram В Одноклассниках Мы Вконтакте
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!

Похожие книги на "Эффективное использование STL"

Книги похожие на "Эффективное использование STL" читать онлайн или скачать бесплатно полные версии.


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

Все книги автора Скотт Мейерс

Скотт Мейерс - все книги автора в одном месте на сайте онлайн библиотеки LibFox.

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

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

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

А что Вы думаете о книге? Оставьте Ваш отзыв.