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

1 ... 9 10 11 [ 12 ] 13 14 15 ... 156


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

GCPtr - шаблонный класс, который перефужает операции указателей * и -> и операцию индексирования массива [ ]. Следовательно, GCPtr создает новый тип указателя и встраивает его в профаммную среду С++. Это позволяет использовать класс GCPtr в значительной степени так же, как обычный указатель языка С++. Однако по причинам, которые будут разъяснены чуть позже в этой же главе, GCPtr не перефужает операции: ++, - и другие арифметические операции, определенные для указателей. Следовательно, никаким другим способом, кроме присваивания, нельзя изменить адрес, на который объект типа GCPtr указывает. Это может показаться существенным ограничением, но это не так, потому что неподдерживаемые операции выполняются с помощью класса iter.

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

О классе GCInfo

Как отмечалось ранее, класс GCPtr поддерживает список, связывающий счетчики ссылок с вьщеленной памятью. Каждый элемент этого списка инкапсулирован в объект типа Gcinfo. Класс Gcinfo хранит счетчик ссылок в поле refcount и указатель на память в поле memPtr. Таким образом, объект GCInfo связывает счетчик ссылок с фрагментом памяти.

В GCInfo определяются еще два поля: isArray и arraySize. Если поле mexnPtr указывает на динамически размещенный массив, то поле isArray становится равным true, а в поле arraysize содержится длина массива.

О классе Iter

Как объяс11ялось ранее, объект GCPtr предоставляет вам доступ к памяти, на которую он указывает, с помощью обычных операций указателей: * и ->, но он не поддерживает арифметические операции указателей. Для этого вам следует использовать объект типа iter, iter - это шаблонный класс, функционально подобный типу iterator библиотеки STL. В нем определены все операции с указателями, в том числе и арифметические. Главная задача класса iter - обрабатывать в цикле элементы распределенного в динамической памяти массива. Этот класс также обеспечивает контроль диапазона (или проверку границ). Получить доступ к нему можно из класса GCPtr с помощью вызова функций beginO или endO, которые действуют почти так же, как их эквиваленты из библиотеки STL.



Важно отметить, что хотя класс iter и тип iterator из библиотеки STL подобны, их нельзя считать полными аналогами и использовать один вместо другого.

О классе OutOfRangeExc

Если объект типа iter обнаруживает попытку выхода за диапазон выделенной памяти, возникает исключение типа OutOfRangeExc. Класс OutOfRangeExc не содержит членов, интересных для задачи, описываемой в этой главе. Это просто тип исключения, которое может генерироваться. Но вы вольны добавить в этот класс функциональные средства, нужные вашим приложениям.

Подробно о классе GCPtr

Класс GCPtr - это сердце сборщика мусора. Он реализует новый тип указателя, который хранит счетчики ссылок для объектов, распределенных в хип-области. Класс также обеспечивает сборшик мусора функциональными средствами для очистки неиспользуемой памяти.

GCPtr - это шаблонный класс со следующим объявлением: Template <class Т, int size=0> class GCPtr {

Класс GCPtr требует, чтобы вы задали тип данных, на которые он будет указывать, вместо обобщенного типа т. Если размещается массив, вы должны указать его размер в параметре size. В противном случае параметр size сохраняет заданное по умолчанию нулевое значение, что свидетельствует об указании на одиночный объект. Далее приведены два примера. GCPtr<int> р; объявляется указатель на целую переменную GCPtr<int, 5> ар; объявляется указатель на массив из 5 целых чисел

р может указывать на одиночные объекты типа int, и ар - на массив из 5 элементов типа int.

Обратите внимание на то, что в примерах вы не использовали операцию *, когда задавали имя объекта типа GCPtr. Это значит, что для создания указателя типа GCPtr на объект типа int не следует применять оператор, подобный приведенному далее.

GCPtr<int> *р; создается указатель на объект типа GCPtr<int>

Это объявление создает обычный указатель С++ с именем р, который может ссылаться на объект типа Gcptr<int>. Оно не декларирует объект GCPtr, который может указывать на переменную типа int. Помните - класс GCPtr самостоятельно описывает указатель.

Будьте внимательны при задании параметра типа для класса GCPtr. Он описывает тип объекта, на который объект GCPtr может указывать. Следова-



хельно, если вы пишете объявление, подобное приведенному далее, вы создаете объект GCPtr, который указывает на указатели int *, а не на переменные типа int.

GCPtr<int *> р; создается объект GCPtr для указания на указатели, ссылающиеся на тип int

Важность проблемы заставляет подробно описать в следующих разделах каждый член класса GCPtr.

Данные-члены класса GCPtr

в классе GCPtr объявляются следующие данные-члены. gclist поддерживает список сбора мусора, static list<GCInfo<T> > gclist;

addr указьшает на вьщеленную память, на которую этот указатель GCPtr ссыпается в данный момент. Т *addr;

/* isArray равен true, если этот GCPtr указывает

на размещенный массив. В противном случае равен false. */

bool isArray; Равен true, если указание на массив

Если этот GCPtr указывает на размещенный массив, arraySize содержит размер массива, xmsigned arraySize; размер массива

static bool first; Равен true, когда создается первый GCPtr.

Поле gclist содержит список объектов типа GCinfo (напоминаю, что объект GCInfo связывает счетчик ссылок с фрагментом выделенной памяти), необходимый для обнаружения сборщиком мусора неиспользуемой памяти. Обратите внимание на то, что gclist - статический член класса GCPtr. Это означает, что для каждого конкретного типа указателя существует только один gclist. Например, для всех указателей типа GCPtr<int> создается один список, а для указателей типа GCPtr<doubie> - другой. Список gclist - это экземпляр класса list библиотеки STL (Standard Template Library). Использование этой библиотеки существенно упрощает код для класса GCPtr, потому что ему нет нужды создавать собственные функции обработки списка.

Класс GCPtr хранит адрес памяти, на которую он указывает, в поле addr. Если он ссылается на распределенный в динамической памяти массив.



1 ... 9 10 11 [ 12 ] 13 14 15 ... 156

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