Д. Стефенс - 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++. Сборник рецептов - читать книгу онлайн бесплатно, автор Д. Стефенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

#include

#include

#include

#include

using namespace std;

static const int ARRAY_SIZE = 5;

template

FwdIter fixOutliersUBound(FwdIter p1,

FwdIter p2, const T& oldVal, const T& newVal) {

for ( ; p1 != p2; ++p1) {

if (greater(*p1, oldVal)) {

*p1 = newVal;

}

}

}

int main() {

list lstStr;

lstStr.push_back("Please");

lstStr.push_back("leave");

lstStr.push_back("a");

lstStr.push_back("message");

// Создать итератор для последовательного перебора элементов списка

for (list::iterator p = lstStr.begin();

p != lstStr.end(); ++p) {

cout << *p << endl;

}

// Или можно использовать reverse_iterator для перебора от конца

// к началу, rbegin возвращает reverse_iterator, указывающий

// на последний элемент, a rend возвращает reverse_iterator, указывающий

// на один-перед-первым.

for (list::reverse_iterator p = lstStr.rbegin();

p != lstStr.rend(); ++p) {

cout << *p << endl;

}

// Перебор диапазона элементов

string arrStr[ARRAY_SIZE] = {"My", "cup", "cup", "runneth", "over"};

for (string* p = &arrStr[0];

p != &arrStr[ARRAY_SIZE]; ++p) {

cout << *p << endl;

}

// Использование стандартных алгоритмов со стандартной последовательностью

list lstStrDest;

unique_copy(&arrStr[0], &arrStr[ARRAY_SIZE],

back_inserter(lstStrDest));

}

Обсуждение

Итератор — это тип, который используется для ссылки на единственный объект в контейнере. Стандартные контейнеры используют итераторы как основной механизм для доступа к содержащимся в них элементам. Итератор ведет себя как указатель; для доступа к объекту, на который указывает итератор, вы его разыменовываете (с помощью операторов *или ->), а для перевода итератора вперед или назад используется синтаксис, аналогичный арифметике указателей. Однако есть несколько причин, по которым итератор — это не то же самое, что указатель. Однако перед тем, как я покажу их, давайте рассмотрим основы использования итераторов.

Использование итераторов

Итератор объявляется с помощью типа, элементы которого с его помощью будут перебираться. Например, в примере 7.1 используется list, так что итератор объявляется вот так.

list::iterator p = lstStr.begin();

Если вы не работали со стандартными контейнерами, то часть этого объявления ::iteratorможет выглядеть несколько необычно. Это вложенный в шаблон класса list typedef, предназначенный именно для этой цели — чтобы пользователи контейнера могли создать итератор для данного конкретного экземпляра шаблона. Это стандартное соглашение, которому следуют все стандартные контейнеры. Например, можно объявить итератор для listили для set, как здесь.

list::iterator p1;

set::iterator p2;

Возвращаясь обратно к нашему примеру, итератор о инициализируется первым элементом последовательности, который возвращается методом begin. Чтобы перейти к следующему элементу, используется operator++. Можно использовать как префиксный инкремент так и постфиксный инкремент ( p++), аналогично указателям на элементы массивов, но префиксный инкремент не создает временного значения, так что он более эффективен и является предпочтительным. Постфиксный инкремент ( p++) должен создавать временную переменную, так как он возвращает значение pдо его инкрементирования. Однако он не может инкрементировать значение после того, как вернет его, так что он вынужден делать копию текущего значения, инкрементировать текущее значение, а затем возвращать временное значение. Создание таких временных переменных с течением времени требует все больших и больших затрат, так что если вам не требуется именно постфиксное поведение, используйте префиксный инкремент.

Как только будет достигнут элемент end, переход на следующий элемент следует прекратить. Или, строго говоря, когда будет достигнут элемент, следующий за end. В отношении стандартных контейнеров принято некое мистическое значение, которое представляет элемент, идущий сразу за последним элементом последовательности, и именно оно возвращается методом end. Этот подход работает в цикле for, как в этом примере:

for (list::iterator p = lstStr.begin();

p != lstStr.end(); ++p) {

cout << *p << endl;

}

Как только pстанет равен end, pбольше не может увеличиваться. Если контейнер пуст, то begin == endравно true, и тело цикла никогда не выполнится. (Однако для проверки пустоты контейнера следует использовать метод empty, а не сравнивать beginи endили использовать выражение вида size == 0.)

Это простое объяснение функциональности итераторов, но это не все. Во-первых, как только что было сказано, итератор работает как rvalueили lvalue, что означает, что его разыменованное значение можно присваивать другим переменным, а можно присвоить новое значение ему. Для того чтобы заменить все элементы в списке строк, можно написать нечто подобное следующему

for (list::iterator p = lstStr.begin();

p != lstStr.end(); ++p) {

*p = "mustard";

}

Так как *pссылается на объект типа string, для присвоения элементу контейнера новой строки используется выражение string::operator=(const char*). Но что, если lstStr — это объект типа const? В этом случае iteratorне работает, так как его разыменовывание дает не-const объект. Здесь требуется использовать const_iterator, который возвращает только rvalue. Представьте, что вы решили написать простую функцию для печати содержимого контейнера. Естественно, что передавать контейнер следует как const-ссылку.

template

void printElements(const T& cont) {

for(T::const_iterator p = cont.begin();

p ! = cont.end(); ++p) {

cout << *p << endl;

}

}

В этой ситуации следует использовать именно const, a const_iteratorпозволит компилятору не дать вам изменить *p.

Время от времени вам также может потребоваться перебирать элементы контейнера в обратном порядке. Это можно сделать с помощью обычного iterator, но также имеется reverse_iterator, который предназначен специально для этой задачи. reverse_iteratorведет себя точно так же, как и обычный iterator, за исключением того, что его инкремент и декремент работают противоположно обычному iteratorи вместо использования методов beginи endконтейнера с ним используются методы rbeginи rend, которые возвращают reverse_iterator. reverse_iteratorпозволяет просматривать последовательность в обратном порядке. Например, вместо инициализации reverse_iteratorс помощью beginон инициализируется с помощью rbegin, который возвращает reverse_iterator, указывающий на последний элемент последовательности. operator++перемещает его назад — по направлению к началу последовательности, rendвозвращает reverse_iterator, который указывает на элемент, находящийся перед первым элементом. Вот как это выглядит.

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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