Вектор — это контейнер, оптимизированный таким образом, чтобы обеспечить быстрый доступ к его элементам по индексу. Класс-контейнер vector определен в файле заголовка в пространстве имен std (подробнее об использовании пространств имен см. главу 17). Вектор можно наращивать по мере необходимости. Предположим, был создан вектор для 10 элементов. После того как в вектор поместили 10 объектов, он оказался целиком заполненным. Если затем к вектору добавить еще один объект, он автоматически увеличит свою вместимость так, что сможет разместить одиннадцатый объект. Вот как выглядит определение класса vector:
template > class vector
{
// члены класса
};
Первый аргумент (class T) означает тип элементов в векторе. Второй аргумент (class А) — это класс распределения, который берет на себя функции диспетчера памяти, ответственного за распределение и освобождение памяти для элементов контейнеров. Принципы построения и выполнения классов распределения затрагивают более сложные темы, которые выходят за рамки этой книги.
По умолчанию элементы создаются с помощью оператора new() и освобождаются с помощью оператора delete(), т.е. для создания нового элемента вызывается стандартный конструктор класса Т. Это служит еще одним аргументом в пользу явного определения стандартного конструктора для ваших собственных классов. Если этого не сделать, то нельзя будет использовать стандартный векторный контейнер для хранения объектов пользовательского класса.
Определить векторы для содержания целых и вещественных чисел можно следующим образом:
vector vInts; // вектор для хранения целых элементов
vector vFloats; // вектор для хранения вещественных элементов
Обычно пользователь имеет представление о том, сколько элементов будет содержаться в векторе. Предположим, на курс прикладной математики в институте набирается не более 50 студентов. Прежде чем создавать вектор для массива студентов, следует побеспокоиться о том, чтобы он был достаточно большим и мог содержать 50 элементов. Стандартный класс vector предоставляет конструктор, который принимает число элементов в качестве параметра. Так что можно определить вектор для 50 студентов следующим образом:
vector MathClass(50);
Компилятор автоматически выделит достаточный объем памяти для хранения записей о 50 студентах. Каждый элемент вектора создается с использованием стандартного конструктора Student::Student().
Количество элементов в векторе можно узнать с помощью функции-члена size(). В данном примере функция-член vStudent.size() возвратит значение 50.
Другая функция-член, capacity(), сообщает, сколько в точности элементов может принять вектор, прежде чем потребуется увеличение его размера. Но об этом речь впереди.
Вектор называется пустым, если он не содержит ни одного элемента, т.е. если его размер равен нулю. Чтобы определить, не является ли вектор пустым, в классе вектора предусмотрена функция-член empty(), которая принимает значение, равное истине, если вектор пустой.
Чтобы записать студента Гарри на курс прикладной математики, т.е. (говоря языком программирования) чтобы назначить объект Harry класса Student вектору MathClass, можно использовать оператор индексирования ([]):
MathClass[5] = Harry;
Индексы начинаются с нуля. Для назначения объекта Harry шестым элементом вектора MathClass здесь используется перегруженный оператор присваивания класса Student. Аналогично, чтобы определить возраст объекта Harry, можно получить доступ к соответствующей записи, используя следующее выражение:
MathClass[5].GetAge();
Как упоминалось выше, при добавлении в вектор большего числа элементов, чем было указано при создании вектора, дополнительное место для нового элемента будет добавлено автоматически. Предположим, курс прикладной математики стал таким популярным, что количество принятых студентов превысило число 50. Возможно, за 51- го студента кто-то замолвил словечко, и декану не осталось ничего другого, как увеличить число студентов на курсе. Так вот, если на курс (в вектор MathClass) захочет записаться 51-я студентка Салли (объект Sally), компилятор спокойно расширит пределы вектора, чтобы "впустить" новое молодое дарование.
Добавлять элемент в вектор можно различными способами. Один из них — с помощью функции-члена push_back():
MathClass.push_back(Sally);
Эта функция-член добавляет новый объект Sally класса Student в конец вектора MathClass. И теперь в векторе MathClass содержится уже 51 элемент, причем к объекту Sally можно обратиться по индексу MathClass[50].
Чтобы функция push_back() была работоспособной, в классе Student нужно определить конструктор-копировщик. В противном случае эта функция не сможет создать копию объекта Sally.
Читать дальше