Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
###Cpp_лкц1_1.09_11_#дляБАК#29_01_12.doc
Скачиваний:
40
Добавлен:
29.04.2019
Размер:
6.42 Mб
Скачать

Глава 12. Контейнерные классы

299

Для прохода но всему вектору вводится переменная i как итератор соответствующего типа (напомню, что операция :: обозначает доступ к области видимости, то есть здесь объявляется переменная i типа «итератор для конкретной специализации шаблона»). С помощью этого итератора осуществляется доступ ко всем по порядку элементам контейнера, начиная с первого. Метод beginO возвращает указатель на первый элемент, метод end() — на элемент, следующий за последним. Реализация гарантирует, что этот указатель определен.

Сравнивать текущее значение с граничным следует именно с помощью операции !=, так как операции < или <- могут быть для данного типа не определены. Операция инкремента (i++) реализована так, чтобы после нее итератор указывал на следующий элемент контейнера в порядке обхода. Доступ к элементу вектора выполняется с помощью операции разадресации, как для обычных указателей.

В данном примере вместо вектора можно было использовать любой последовательный контейнер путем простой замены слова vector на deque или list. При этом изменилось бы внутреннее представление данных и набор доступных операций, а в поведении программы никаких изменений не произошло бы.

Однако если вместо цикла for вставить фрагмент

for (int i = 0; i<v.size(); i++) cout « v[i] « " ";

в котором использована операция доступа по индексу [ ], программа не будет работать для контейнера типа list, поскольку в нем эта операция не определена.

Векторы (vector)

Для создания вектора можно воспользоваться следующими конструкторами (приведена упрощенная запись):

explicit vectorO; // 1

explicit vector (si ze_type n, const T& value = TO); /7 2

template <class InputIter> // 3

vector(InputIter first. Inputlter last);

vector(const vector<T>& x); //4

Ключевое слово explicit используется для того, чтобы при создании объекта запретить выполняемое неявно преобразование при присваивании значения другого типа (см. также с. 197).

Конструктор 1 является конструктором по умолчанию.

Конструктор 2 создает вектор длиной п и заполняет его одинаковыми элементами — копиями val ue.

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

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

300

Часть III. Стандартная библиотека

ПРИМЕЧАНИЕ

Элементы любого контейнера являются копиями вставляемых в него объектов. Поэтому для них должны быть определены конструктор копирования и операция присваивания.

Конструктор 3 создает вектор путем копирования указанного с помощью итераторов диапазона элементов. Тип итераторов должен быть «для чтения».

Конструктор 4 является конструктором копирования.

Примеры конструкторов:

// Создается вектор из 10 равных единице элементов: vector <int> v2 (10. 1); // Создается вектор, равный вектору vl: vector <int> v4 (vl);

// Создается вектор из двух элементов, равных первым двум элементам vl: vector <int> v3 (vl.beginO. vl.beginO + 2); // Создается вектор из 10 объектов класса monstr (см. с. 183) // (работает конструктор по умолчанию): vector <monstr> ml (10):

// Создается вектор из 5 объектов класса monstr с заданным именем // (работает конструктор с параметром char*): vector <monstr> m2 (5, monstr("Вася")); В шаблоне vector определены операция присваивания и функция копирования: vector<T>& operator=(const vector<T>& x): void assign(size_type n, const T& value): template <class Inputlter>

void assigndnputlter first. Inputlter last):

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

Функция assign в первой форме аналогична по действию конструктору 2, но применяется к существующему объекту. Функция assign во второй форме предназначена для присваивания элементам вызывающего вектора значений из диапазона, определяемого итераторами first и last, аналогично конструктору 3, например:

vector <int> vl, v2:

// Первым 10 элементам вектора vl присваивается значение 1: vl.assign(lO.l):

// Первым 3 элементам вектора vl присваиваются значения vl[5], vl[6]. vl[7]: v2.assign(vl.begin() + 5. vl.beginO + 8): Итераторы класса vector перечислены в табл. 12.

Доступ к элементам вектора осуществляется с помощью следующих операций и методов:

reference operator[](size_type n);

const_reference operator[](size_type n) const: