C++ | страница 25



1.11 Вектора

Встроенное в С++ понятие вектора было разработано так, чтобы обеспечить максимальную эффективность выполнения при минимальном расходе памяти. Оно также (особенно когда используется совместно с указателями) является весьма универсальным инструментом для построения средств более высокого уровня. Вы могли бы, конечно, возразить, что размер вектора должен задаваться как константа, что нет проверки выхода за границы вектора и т.д. Ответ на подобные возражения таков: «Вы можете запрограммировать это сами.» Давайте посмотрим, действительно ли оправдан такой ответ. Другими словами, проверим средства абстракции языка С++, попытавшись реализовать эти возможности для векторных типов, которые мы создадим сами, и посмотрим, какие с этим связаны трудности, каких это требует затрат, и насколько получившиеся векторные типы удобны в обращении. class vector (* int* v; int sz; public: vector(int); // конструктор ~vector(); // деструктор int size() (* return sz; *) void set_size(int); int amp; operator[](int); int amp; elem(int i) (* return v[i]; *) *); Функция size возвращает число элементов вектора, таким образом индексы должны лежать в диапазоне 0 ... size()-1. Функция set_size сделана для изменения этого размера, elem обеспечивает доступ к элементам без проверки индекса, а operator[] дает доступ с проверкой границ.

Идея состоит в том, чтобы класс сам был структурой фиксированного размера, управляющей доступом к фактической памяти вектора, которая выделяется конструктором вектора с помощью распределителя свободной памяти new:

vector::vector(int s) (* if (s«=0) error(„bad vector size“); // плохой размер вектора sz = s; v = new int[s]; *)

Теперь вы можете описывать вектора типа vector почти столь же элегантно, как и вектора, встроенные в сам язык:

vector v1(100); vector v2(nelem*2-4);

Операцию доступа можно определить как

int amp; vector::operator[](int i) (* if(i«0 !! sz„=i) error(«vector index out of range“); // индекс выходит за границы вектора return v[i]; *)

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

v1[x] = v2[y];

Функция со странным именем ~vector – это деструктор, то есть функция, описанная для того, чтобы она неявно вызывалась, когда объект класса выходит из области видимости. Деструктор класса C имеет имя ~C. Если его определить как