Главная arrow С++ (часть 4) arrow Подробно о классе GCPtr

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

Класс GCPtr — это сердце сборщика мусора. Он реализует новый тип указателя, который хранит счетчики ссылок для объектов, распределенных в хип-области. Класс также обеспечивает сборщик мусора функциональными средствами для очистки неиспользуемой памяти.
GCPtr — это шаблонный класс со следующим объявлением: Template <class T, 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 содержит размер массива, unsigned arraySize; // размер массива
static bool first; // Равен true, когда создается первый GCPtr.
Поле gclist содержит список объектов типа GClnfo (напоминаю, что объект Gcinfo связывает счетчик ссылок с фрагментом выделенной памяти), необходимый для обнаружения сборщиком мусора неиспользуемой памяти. Обратите внимание на то, что gclist — статический член класса GCPtr. Это означает, что для каждого конкретного типа указателя существует только один gclist. Например, для всех указателей типа GCPtr<int> создается один список, а для указателей типа GCPtr<doubie> — другой. Список gclist — это экземпляр класса list библиотеки STL (Standard Template Library). Использование этой библиотеки существенно упрощает код для класса GCPtr, потому что ему нет нужды создавать собственные функции обработки списка.
Класс GCPtr хранит адрес памяти, на которую он указывает, в поле addr. Если он ссылается на распределенный в динамической памяти массив, то поле isArray будет равно true, а длина массива будет содержаться в поле arraySize.
Поле first — статическая переменная, первоначально равная true. Это флаг, который конструктор класса GCPtr использует для определения момента создания первого объекта этого типа. После того как первый такой объект создан, полю first присваивается значение false. Это поле применяется для регистрации функции завершения, которая будет вызываться для закрытия сборщика мусора, когда заканчивается основная программа.