Главная arrow С++ (часть 3) arrow Класс Iter

Класс Iter

Класс iter реализует объект-итератор, применяемый для обработки в цикле элементов размещенного в динамической памяти массива. Технически этот класс не обязателен, так как объект GCPtr может быть преобразован в нормальный указатель соответствующего базового типа, но у класса iter есть два достоинства. Во-первых, способ циклической обработки элементов массива в нем подобен тому, который используется при обработке содержимого контейнеров в библиотеке STL. Следовательно, синтаксис описания класса iter привычен. Во-вторых, класс iter не допускает выхода за границы массива. Таким образом, он является безопасной альтернативой нормального указателя. Однако следует понимать, что класс iter не участвует в сборе мусора. Следовательно, если базовый объект класса GCPtr, на котором базируется объект iter, выходит за пределы области видимости, память на которую указывает базовый объект, будет очищена вне зависимости от того, обращается ли к ней объект iter.
Класс iter — это шаблонный класс, который определяется следующим образом:
Template <class T> class Iter {
Тип данных, на которые указывает класс iter, передается через класс т.
В классе iter определены следующие экземпляры переменных (instance
variables):
T *ptr;     // значение текущего указателя
T *end;      // указывает на элемент, следующий за последним элементом T *begin; // указывает на начало распределенного в памяти массива
// неизвестной длины; unsigned length; // длина массива
Текушее значение адреса содержится в переменной ptr. Адрес начала массива хранится в переменной begin, а адрес элемента, следующего за последним, — в переменной end. Размер массива указывается в переменной length.
В классе iter определены два конструктора, приведенные далее. Первый — конструктор по умолчанию. Второй создает объект iter, задавая начальное значение переменной ptr и указатели на начало и конец массива.
Iter О {
ptr = end = begin = NULL; length = 0;
}
Iter(T *p, T *first, T *last) { ptr =   p; end = last; begin = first; length = last - first;
}
В программе сборщика мусора, приведенной в этой главе, начальное значение переменной ptr всегда равно значению переменной begin. Но вы можете создавать объекты типа iter с другим начальным значением.
Для того чтобы объекты класса iter могли вести себя подобно указателям, в классе перегружены операции: * и ->, и операция индексирования [ ], их код приведен далее.
// Возвращает значение, на которое указывает ptr. //Не разрешает выход за пределы диапазона. Т boperator*()  {
if( (ptr >= end)  I I  (ptr < begin) ) throw OutOfRangeExc();
return *ptr;
}
11 Возвращает адрес, содержащийся в ptr. И Не разрешает выход за пределы диапазона. т *operator->() {
if( (ptr >= end)  I I  (ptr < begin) ) throw OutOfRangeExc();
return ptr;
У
II Возвращает ссылку на объект
// с заданным индексом. Не разрешает выход
II за. пределы диапазона.
Т boperator[](int i)  {
if( (i < 0)  ||  (i >= (end-begin))  ) throw OutOfRangeExc();
return ptr[i];
}
Операция * возвращает ссылку на указываемый элемент массива. Операция -> возвращает адрес этого элемента. Операция [ ] возвращает ссылку на элемент, индекс которого задан. Обратите внимание на то, что описанные операции не допускают выхода за границы массива. При любой подобной попытке генерируется исключение класса outofRangeExe.
В классе iter определены различные арифметические операции с указателями, такие как: ++, — и т. д., которые изменяют объект iter. Эти операции позволят вам в цикле обрабатывать размещенный в динамической памяти массив. Для сохранения высокой скорости выполнения ни одна из арифметических операций не обрабатывает самостоятельно выход за границы массива. Однако любая попытка обратиться к элементу, находящемуся за пределами этих границ, сгенерирует исключение, которое препятствует возникновению ошибки. В классе iter определены также операции отношения. Операции отношения, как и арифметические операции, просты и понятны. В классе iter описана функция-утилита sizeo, которая возвращает размер массива, на который указывает объект iter.
Как уже отмечалось ранее, в классе GCPtr с помощью спецификатора typedef задан синоним CGiterator типа iter<T> для каждого экземпляра класса, упрощающий объявление итератора. Это означает, что для применения итератора класса iter в любом объекте типа GCPtr вы можете использовать ИМЯ Типа CG It era tor.