Программирование >>  Формирование пользовательского контейнера 

1 ... 106 107 108 [ 109 ] 110 111 112 ... 156


Запоминаю, что конструкторы класса RangeArray не применяют операцию pew ДЛЯ выделения памяти, а деструктор - операцию delete для ее очистки, вместо этого они используют функции-члены распределителя памяти. Та-иой подход позволяет пользователю задавать альтернативные средства управления памятью, отведенной контейнеру.

функции перегрузки операций класса RangeArray

В листинге 8.1 есть три функции-члена для перефузки операций, определенные в классе RangeArray. Первые две, приведенные далее, используются для перефузки операции индексирования [].

Возвращает ссылку на заданный элемент.

Т fcoperator[]{int i)

return arrayptr [ i - lowerbotind] ;

Возвращает константные ссылки на заданный элемент.

const Т &operator[](int i) const

return arrayptr [i - lowerbotind] ;

Для полностью сформированного контейнера нужны обе версии операции индексирования: константная и неконстантная. Приведенные функции обеспечивают механизм индексирования объекта типа RangeArray. Обратите особое внимание на способ индексирования массива, заданного указателем arrayptr. Помните, ЧТО arrayptr указывает на стандартный массив языка С++. Следовательно, индекс, передаваемый в переменной i, следует для этого массива преобразовать в индекс с отсчетом от нуля. Напоминаю, что поле lowerbound содержит наименьшее значение индекса объекта RangeArray. Таким образом, для получения индекса с отсчетом от нуля из i

вычитается lowerbound.

И еще одно замечание: в перефуженной операции индексирования [ ] () не выполняется никакой проверки фаниц. Стандарт библиотеки STL не фебу-ет такой проверки, и она не включена в код. Это резонно, потому что, за исключением задаваемого пользователем диапазона, объект RangeArray ведет себя так же, как нормальный массив (вспомните, в обычных массивах С++ не выполняется никакой проверки фаниц). Конечно, если вы захотите, такую проверку можно добавить в операцию [ ] ().

Далее приведена немного более сложная перефуженная операция присваи-ния = ().



334 {лаеав

Присваивает один контейнер другому, tenplate <class Т, class А> RangeArray<T, А> & RangeArray<T, А>::operator=(const RangeArray<T, A> &o) {

Вызьшает деструкторы для элементов в контейнере-приемнике. for(size type 1=0; i < sizeO; i++) a.destroy(&arrayptr[i]);

Освобождает исходную память, а.deallocate(arrayptr, size());

Выделяет память для нового размера, arrayptr = a.allocate(o.size()); upperbotind = о. upperbound; lowerbound = o.lowerbotind; len = o.len;

Создает копию.

for{size type i=0; i < sizeO; i++) arrayptr[i] = о.arrayptr[i];

return *this;

Сначала она уничтожает созданные ранее объекты в контейнере-приемнике и освобождает отведенную им память. Далее выделяется память, достаточная для хранения содержимого объекта-источника. Затем устанавливаются соответствующие значения переменных-членов и копируются элементы. В конце возвращается сс>1лка на объект-приемник.

Функции вставки

Стандарт библиотеки STL требует, чтобы последовательный контейнер под держивал три варианта функции insert о: один для вставки значения, другой для вставки множественных копий значения и третий для вставки ряда значений. Далее приведен первый вариант функции insert (). Вставляет val по адресу р. tenplate <class Т, class А> typename RangeArray<T, А>::iterator

RangeArray<T, A>::insert(iterator p, const T &val) ♦



iterator q; si2e type i. j;

Получает необходимую память. Т *tinp = a.allocate(size() + 1);

Копирует существующие элементы в новый массив, если возможно, вставляет новый элемент. for(i=j=0; i < SizeO; i++, j++) { if(&arrayptr[i] == p) { tinp[j] = val; q = &tinp[j];

tinp[j] = arrayptr[i];

В противном случае новый элемент перемещается в конец, if(р == endO) {

tinp[j] = val;

q = &tinp[j];

Корректирует длину len и границы. len++;

if(p < &arrayptr [abs( lowerbound) ])

lowerbotind-; else

upperbotind++;

Вызывает деструкторы для элементов старого контейнера. for(size type i=0; i < size()-l; i++) a.destroy(&arrayptr[i]);

Очищает память, отведенную для старого контейнера, а.deallocate(arrayptr, size О-1);

arrayptr = tnp;

return q;



1 ... 106 107 108 [ 109 ] 110 111 112 ... 156

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика