|
Программирование >> Формирование пользовательского контейнера
336 Главой Первый вариант функции вставляет элемент в позицию, заданную итератором р, передаваемым в ее первом параметре. Функция возвращает итератор, указывающий на вставленный элемент. Она вьшеляет сегмент памяти, достаточный для хранения всех существующих элементов и нового. Затем она копирует существующие элементы во вновь вьщеленную память, вставляя новый элемент в соответствующее место. Далее функция обновляет переменные-члены len и upperbound ИЛИ lowerbound соответственно. После этого уничтожаются объекты из исходного контейнера RangeArray, и указателю arrayptr присваивается адрес нового выделенного сегмента памяти. В конце концов, функция возвращает указатель на вставленный объект. Теперь посмотрите внимательно на фрагмент кода, в котором обновляются значения переменных upperbound или lowerbound. Помните, что массив может увеличиваться как в положительном, так и в отрицательном направлениях, в зависимости от того, в какую его часть, положительную или отрицательную, выполняется вставка. Следовательно, нужно определить, куда вставляется новый элемент, и изменить соответствующую границу. Для этого итератор, передаваемый в параметре р, сравнивается с адресом элемента arrayptr [lowerbound]. Если итератор меньще этого элемента, увеличивается отрицательная часть массива, в противном случае - положительная часть. Далее приведены следующие два варианта функции insert (), определенные посредством первого варианта. Вставляет num копий значения val, начиная с адреса р. void insert(iterator р, int num, const T &val) for(; num>0; num-) p = insert(p, val) + 1; Вставляет ряд элементов, заданный значениями start и stop, по адресу р. void insert(iterator р, iterator start, iterator stop) while(start != stop) { p = insert(p, *start) + 1; start++; Функции очистки Последовательные контейнеры должны поддерживать два варианта функии erase (). Первый - удаляет элемент, на который указывает итератор. В этом случае функция возвращает итератор, указывающий на элемент, располо- женный следом за удаленным, или end о, если был удален последний элемент. Далее приведен первый вариант функции. Стирает элемент по адресу р. template <class Т, class А> typename RangeArray<T, А>::iterator RangeArray<T, A>::erase(i terator p) { iterator q = p; Уничтожает стертый элемент. if(p != endO) a.destroy(p); Корректирует длину len и границы. \ len-; if(p < &arrayptr[abs(lowerbound)]) lowerbound++; else upperbound-; Уплотняет оставшиеся элементы, for( ; p < end(); p++) *p = *(p+l); - return q; } В этом варианте функции освобождается память, занимаемая стираемым элементом, корректируются нижняя или верхняя фаницы соответственно, и потом оставшиеся элементы уплотняются. Второй вариант функции, приведенный далее, определен с помощью первого варианта. В этом варианте стирается ряд элементов. Функция возвращает итератор, указывающий на последний элемент заданного ряда (т. е. на элемент по адресу stop). Таким образом, она удаляет элементы в диапазоне от start до stop-i включительно. Стирает заданный диапазон элементов, iterator erase(iterator start, iterator stop) { iterator p = endO; for (int i=stop-start; i > 0; i~) р = erase(start); return p; Функции Push и Pop В класс RangeArray включены приведенные далее следующие функции: push back(), pop back(), push front() И pop front(). Как ВИДНО ИЗ кода, они реализованы с помощью функций insert о и eraseo, и действие их очевидно. Добавляет элемент в конец, void push back(const Т &val) { insert(end(), val); Удаляет последний элемент. void pop back() erase (end 0-1) ; Добавляет элемент в начало, void push front(const T &val) { insert(begin(), val); . Удаляет начальный элемент. void pop front() erase(begin()); Функции frontO и backl) Приведенные далее функции front о и back о просто возвращают итератор, указывающий на начало и конец массива соответственно. Их реализация проста и понятна. Обратите внимание на то, что необходимы оба варианта функций: константный и неконстантный. Возвращает ссылку на первый элемент. Т ficfrontO
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |