Д. Стефенс - C++. Сборник рецептов

Тут можно читать онлайн Д. Стефенс - C++. Сборник рецептов - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство КУДИЦ-ПРЕСС, год 2007. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    C++. Сборник рецептов
  • Автор:
  • Жанр:
  • Издательство:
    КУДИЦ-ПРЕСС
  • Год:
    2007
  • Город:
    Москва
  • ISBN:
    5-91136-030-6
  • Рейтинг:
    3.9/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Д. Стефенс - C++. Сборник рецептов краткое содержание

C++. Сборник рецептов - описание и краткое содержание, автор Д. Стефенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.

C++. Сборник рецептов - читать онлайн бесплатно полную версию (весь текст целиком)

C++. Сборник рецептов - читать книгу онлайн бесплатно, автор Д. Стефенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

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

Этот рецепт описывал итераторы, как они используются для контейнеров. Но шаблон итераторов используется не только для контейнеров, и, таким образом, имеются другие типы итераторов. Имеются потоковые итераторы, итераторы буферов потоков и итераторы хранения в необработанном виде, но они здесь не описываются.

Смотри также

Глава 6.

7.2. Удаление объектов из контейнера

Проблема

Требуется удалить объекты из контейнера.

Решение

Для удаления одного или диапазона элементов используйте метод контейнера erase или один из стандартных алгоритмов. Пример 7.2 показывает пару различных способов удаления элементов из последовательностей.

Пример 7.2. Удаление элементов из контейнера

#include

#include

#include

#include

#include

#include "utils.h" // Для printContainer(): см. 7.10

using namespace std;

int main() {

list lstStr;

lstStr.push_back("On");

lstStr.push_back("a");

lstStr.push_back("cloudy");

lstStr.push_back("cloudy");

lstStr.push_back("day");

list::iterator p;

// Найти то что требуется, с помощью find

p = find(lstStr.begin(), lstStr.end(), "day");

p = lstStr.erase(p); // Теперь p указывает на последний элемент

// Или для удаления всех вхождений чего-либо используйте remove

lstStr.erase(remove(lstStr.begin(), lstStr.end(), "cloudy"),

listStr.end());

printContainer(lstStr); // См. 7.10

}

Обсуждение

Для удаления одного или нескольких элементов из контейнера используйте метод erase. Все контейнеры содержат два перегруженных erase: один принимает единственный аргумент iterator, который указывает на элемент, который требуется удалить, а другой принимает два аргумента, которые представляют диапазон удаляемых элементов. Чтобы удалить один элемент, получите iterator, указывающий на этот элемент, и передайте этот iteratorв erase, как в примере 7.2.

p = find(lstStr.begin(), lstStr.end(), "day");

p = lstStr.erase(p);

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

В последовательностях eraseвозвращает iterator, который ссылается на первый элемент, следующий непосредственно за последним удаленным элементом, что может оказаться end, если был удален последний элемент последовательности. Сложность этой операции для каждого контейнера различна, так как последовательности реализованы по- разному. Например, из-за того, что все элементы vectorхранятся в непрерывном фрагменте памяти, удаление из него элемента, кроме первого и последнего, с целью заполнения образовавшегося промежутка требует сдвига всех последующих элементов в сторону начала. Это приводит к значительному снижению производительности (в линейном отношении), и именно по этой причине не следует использовать vector, если требуется удалять (или вставлять, что в данном случае приводит к таким же последствиям) элементы где-либо, кроме концов. Более подробно этот вопрос обсуждается в рецепте 6.2.

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

eraseудобен, но не интересен. Если требуется большая гибкость в выражении того, что требуется удалить, следует обратить внимание на стандартные алгоритмы (из ). Рассмотрим такую строку из примера 7.2.

lstStr.erase(std::remove(lstStr.begin(), lstStr.end(), "cloudy"),

lstStr.end());

Обратите внимание, что я использую erase, но на этот раз по какой-то причине мне требуется удалить из listвсе вхождения слова «cloudy», removeвозвращает iterator, который передается в eraseкак начало удаляемого диапазона, a endпередается в eraseкак конечная точка диапазона. В результате удаляются все объекты obj(вызывая их метод delete) из диапазона, для которого obj == "cloudy"равно истине. Но поведение этой строки может оказаться не совсем таким, как ожидается. Здесь мне требуется пояснить некоторую терминологию.

removeна самом деле ничего не удаляет . Он перемещает все, что не равно указанному значению, в начало последовательности и возвращает iterator, который ссылается на первый элемент, следующий за этими перемещенными элементами. Затем вы должны вызвать eraseдля контейнера, чтобы удалить объекты между [ p, end), где p— это iterator, возвращенный remove.

removeтакже имеет несколько вариантов. Что, если требуется удалить элементы, которые удовлетворяют некоторому предикату, а не просто равны какому-то значению? Используйте remove_if. Например, представьте, что есть класс с именем Conn, который представляет какой-то тип соединений. Если это соединение простаивает больше определенного значения, его требуется удалить. Во-первых, создайте функтор, как здесь.

struct IdleConnFn :

public std::unary_function { // Включите эту строку,

bool operator() (const Conn& c) const { // чтобы он работал с

if (с.getIdleTime() > TIMEOUT) { // другими объектами из

return(true); //

} else return(false);

}

} idle;

Затем вызовите remove_ifс erase и передайте в него новый функтор, как здесь.

vec.erase(std::remove_if(vec.begin(), vec.end(), idle), vec.end());

Есть причина, по которой такие функторы следует наследовать от unary_function, unary_functionопределяет несколько typedef, используемых другими функторами из , и если они их не найдут, то другие функторы не скомпилируются. Например, если вы очень злы и хотите удалить все не задействованные в данный момент соединения, то в функторе проверки на простой можно использовать функтор not1.

vec.erase(std::remove_if(vec.begin(), vec.end(); std::not1(idle)),

vec.end());

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

Интервал:

Закладка:

Сделать


Д. Стефенс читать все книги автора по порядку

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




C++. Сборник рецептов отзывы


Отзывы читателей о книге C++. Сборник рецептов, автор: Д. Стефенс. Читайте комментарии и мнения людей о произведении.


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

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