Как упоминалось выше, контейнеры представляют собой объекты STL, которые предназначены для хранения данных. Контейнеры, определяемые в STL, представлены в табл. 21.1. В ней также указаны заголовки, которые необходимо включать в программу при использовании каждого контейнера. Но несмотря на то, что класс string
также является контейнером, позволяющим хранить и обрабатывать символьные строки, он в эту таблицу не включен и рассматривается ниже в этой главе.
Поскольку имена типов в объявлениях шаблонных классов произвольны, контейнерные классы объявляют typedef
-версии этих типов, что конкретизирует имена типов. Некоторые из наиболее популярных typedef-имен приведены ниже.
Поскольку в одной главе невозможно рассмотреть все контейнеры, в следующих разделах мы представим только три из них: vector
, list и map. Если вы поймете, как работают эти три контейнера, у вас не будет проблем с использованием остальных.Векторы
Векторы представляют собой динамические массивы.
Одним из контейнеров самого широкого назначения является вектор. Класс vector
поддерживает динамический массив, который при необходимости может увеличивать свой размер. Как вы знаете, в C++ размер массива фиксируется во время компиляции. И хотя это самый эффективный способ реализации массивов, он в то же время является и самым ограничивающим, поскольку размер массива нельзя изменять во время выполнения программы. Эта проблема решается с помощью вектора, который по мере необходимости обеспечивает выделение дополнительного объема памяти. Несмотря на то что вектор — это динамический массив, тем не менее, для доступа к его элементам можно использовать стандартное обозначение индексации массивов.Вот как выглядит шаблонная спецификация для класса vector:
template > class vector
Здесь T
— тип сохраняемых данных, а элемент Allocator означает распределитель памяти, который по умолчанию использует стандартный распределитель. Класс vector имеет следующие конструкторы.
explicit vector(const Allocator &a = Allocator());
explicit vector(size_type num, const T &val = T(), const Allocator &a = Allocator());
vector(const vector &ob);
template vector(InIter start, InIter end, const Allocator &a = Allocator());
Первая форма конструктора предназначена для создания пустого вектора. Вторая создает вектор, который содержит num
элементов со значением val, причем значение val может быть установлено по умолчанию. Третья форма позволяет создать вектор, который содержит те же элементы, что и заданный вектор ob. Четвертая предназначена для создания вектора, который содержит элементы в диапазоне, заданном параметрами-итераторами start и end.Ради достижения максимальной гибкости и переносимости любой объект, который предназначен для хранения в векторе, должен определяться конструктором по умолчанию. Кроме того, он должен определять операции "<"
и "==" Некоторые компиляторы могут потребовать определения и других операторов сравнения. (В виду существования различных реализаций для получения точной информации о требованиях, предъявляемых вашим компилятором, следует обратиться к прилагаемой к нему документации.) Все встроенные типы автоматически удовлетворяют этим требованиям.Несмотря на то что приведенный выше синтаксис шаблона выглядит довольно "массивно", в объявлении вектора нет ничего сложного. Рассмотрим несколько примеров.
vector iv; /* Создание вектора нулевой длины для хранения int-значений. */
vector cv(5); /* Создание 5-элементного вектора для хранения char-значений. */
vector cv(5, 'х'); /* Инициализация 5-элементного char-вектора. */
vector iv2(iv); /* Создание int-вектора на основе int-вектора iv. */
Для класса vector определены следующие операторы сравнения:
==, <, <=, !=, > и >=