Чтение онлайн

ЖАНРЫ

Освой самостоятельно С++ за 21 день.

Либерти Джесс

Шрифт:

В строках 104 и 105 вновь используется оператор индексирования ([]), чтобы изменить переменные-члены первого объекта в векторе GrowingClass.

Рекомендуется:Определяйте стандартный конструктор для класса, если его объекты будут содержаться в векторе. Определяйте конструктор-копировщик для такого класса. Определяйте для такого класса перегруженный оператор присваивания.

Класс-контейнер вектора имеет и другие функции-члены. Функция front возвращает ссылку на первый элемент в списке, а функция back — на последний. Функция at работает подобно

оператору индексирования ([]). Она более безопасна, поскольку проверяет, попадает ли переданный ей индекс в диапазон доступных элементов. Если адрес оказывается вне диапазона, эта функция генерирует исключение out_of_range. (Исключительные ситуации рассматриваются на следующем занятии.)

Функция insert вставляет один или несколько узлов (элементов) в текущую позицию вектора. Функция Pop_back удаляет из вектора последний элемент. Наконец, функция remove удаляет из вектора один или несколько элементов.

Список

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

Класс-контейнер библиотеки STL list определен в файле заголовка <list> в пространстве имен std. Класс list выполнен как двунаправленный связанный список, в котором каждый узел содержит указатели как на предыдущий, так и на последующий узел списка.

Класс list имеет все функции-члены, предоставляемые векторным классом. Как вы помните, список можно пройти, следуя по связям между узлами, реализованным с помощью указателей. Стандартный класс-контейнер list с той же целью использует алгоритм, называемый итератором.

Итератор — это обобщение указателя. Чтобы отыскать узел, на который указывает итератор, его нужно разыменовывать. Использование итераторов для доступа к узлам списка демонстрируется в листинге 19.9.

Листинг 19.9. Навигация по списку с ппмощью итератора

1: #include <iostream>

2: #include <list>

3: using namespace std;

4:

5: typedef list<int> IntegerList;

6:

7: int main

8: {

9: IntegerList intList;

10:

11: for (int i = 1; i <= 10; ++i)

12: intList.push_back(i * 2);

13:

14: for (IntegerList::const_iterator ci = intList.begin;

15: ci!= intList.end; ++ci)

16: cout << *ci << " ";

17:

18: return 0;

19: }

Результат:

2 4 6 8 10 12 14 16 18 20

Анализ: В строке 9 объект intList определен как список целых чисел. В строках 11 и 12 с помощью функции push_back в список добавляются первые 10 положительных четных чисел.

В строках 14-16 мы обращаемся к каждому узлу в списке, используя константный итератор. Константность указывает, что мы не собираемся изменять узлы с помощью этого итератора. Если бы мы хотели изменить узел, на который указывает итератор, пришлось бы использовать переменный итератор:

intList::iterator

Функция-член begin возвращает итератор на первый узел списка. Оператор инкремента (++) можно использовать для перехода к итератору следующего узла. Функция-член end, что может показаться странным, возвращает итератор на узел, расположенный за последним узлом списка. Часто метод end используют для определения допустимых границ списка.

Разыменование итератора (для возвращения связанного с ним узла) происходит аналогично разыменованию указателя, как показано в строке 16.

Хотя понятие итератора было введено только при рассмотрении

класса list, итераторы можно использовать и с векторными классами. В дополнение к функциям-членам, с которыми вы познакомились в векторном классе, базовый класс списка тоже представляет функции push_front и pop_front, которые работают точно так же, как и функции push_back и pop_back. Но вместо добавления и удаления элементов в конце списка, они добавляют и удаляют элементы в его начале.

Контейнер двухсторонней очереди

Двухсторонняя очередь подобна двунаправленному вектору — она наследует эффективность класса-контейнера vector по операциям последовательного чтения и записи. Но, кроме того, класс контейнер deque обеспечивает оптимизированное добавление и удаление узлов с обоих концов очереди. Эти операции реализованы аналогично классу-контейнеру list, где процесс выделения памяти запускается только для новых элементов. Эта особенность класса двухсторонней очереди устраняет потребность перераспределения целого контейнера в новую область памяти, как это приходится делать в векторном классе. Поэтому двухсторонние очереди идеально подходят для приложений, в которых вставки и удаления происходят с двух концов массива и для которых имеет важное значение последовательный доступ к элементам. Примером такого приложения может служить имитатор сборки поезда, в котором вагоны могут присоединяться к поезду с обоих концов.

Стеки

Одной из самых распространенных в программировании структур данных является стек. Однако стек не используется как независимый контейнерный класс, скорее, его можно назвать оболочкой контейнера. Шаблонный класс stack определен в файле заголовка <stack> в пространстве имен std.

Стек — это непрерывный выделенный блок памяти, который может расширяться или сжиматься в хвостовой части, т.е. к элементам стека можно обращаться или удалять только с одного конца. Вы уже видели подобные характеристики в последовательных контейнерах, особенно в классах vector и deque. Фактически для реализации стека можно использовать любой последовательный контейнер, который поддерживает функции back, push_back и pop_back. Большинство других методов контейнеров для работы стека не используются, поэтому они и не предоставляются классом stack.

Базовый шаблонный класс stack библиотеки STL шаблона разработан для поддержания объектов любого типа. Единственное ограничение состоит в том, что все элементы должны иметь один и тот же тип.

Данные в стеке организованы по принципу "последним вошел — первым вышел". Ее можно сравнить с переполненным лифтом: первый человек, вошедший в лифт, припирается к стене, а последний втиснувшийся стоит прямо у двери. Когда лифт поднимается на указанный кем-то из пассажиров этаж, тот, кто зашел последним, должен выйти первым, Если кто-нибудь (из стоящих посередине пассажиров) захочет выйти из лифта раньше других, то все, кто находится между ним и дверью, должны выйти из лифта, выпустив его, а затем вернуться обратно.

Открытый конец стека называется вершиной стека, а действия, выполняемые с элементами стека, — операциями помещения (push) и выталкивания (pop) из стека. Для класса stack эти общепринятые термины остаются в силе.

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

Поделиться с друзьями: