|
Программирование >> Формирование пользовательского контейнера
Запоминаю, что конструкторы класса 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;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |