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

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


то поле isArray будет равно true, а длина массива будет содержаться в поле arraySize.

Поле first - статическая переменная, первоначально равная true. Это флаг, который конструктор класса ccptr использует для определения момента создания первого объекта этого типа. После того как первый такой объект создан, полю first присваивается значение false. Это поле применяется для регистрации функции завершения, которая будет вызываться для закрытия сборщика мусора, когда заканчивается основная программа.

Функция findPtrlnfoO

в классе GCPtr объявляется функция findPtrinfo() с уровнем доступа private. Это функция ищет в списке gclist заданный адрес и возвращает индекс найденного элемента. Если адрес не найден, возвращается итератор, указывающий на конец списка. Эта функция используется внутри класса ccPtr для обновления значений счетчиков ссылок объектов, хранящихся в списке gclist. Далее приводится код ее реализации.

Находит указатель в списке gclist. template <class Т, int size> typename list<GCInfo<T> >::iterator GCPtr<T. size>::findPtrInfo(T *ptr) {

list<GCInfo<T> >::iterator p;

Находит ptr в gclist.

for(p = gclist.beginO; p != gclist.endO; p++) if(p->memPtr == ptr) return p; return p;

Спецификатор typedef р\я синонима GCIterator

в начале секции public класса ccptr есть спецификатор typedef для типа iter<T> и его синонима Gciterator. Этот спецификатор связан с каждым экземпляром класса GCPtr и устраняет необходимость определения параметра типа каждый раз, когда нужен объект iter для конкретного варианта GCPtr, что упрощает объявление итератора. Для получения итератора участка памяти, на который указывает конкретный объект ccptr, вы можете использовать конструкцию, подобную приведенной далее:

GCPtr<int>::GCIterator itr;



Конструктор класса GCPtr

Далее приведен код конструктора для класса GCPtr.

конструктор для инициализированного и неинициализированного объектов. GCPtr(Т *t=NULL) {

Регистрирует shutdown() как функцию завершения, if(first) atexit(shutdown); first = false;

list<GCInfo<T> >::iterator p;

p = findPtrlnfo(t);

Если t уже есть в списке gclist,

увеличивает его счетчик ссылок.

В противном случае добавляет его в список.

if(p != gclist.endO)

p->refcount++; увеличение счетчика ссылок else {

Создает и запоминает новый элемент.

GCInfo<T> gcObj(t, size); gclist.push front(gcObj);

addr = t;

arraySize = size;

if(size > 0) isArray = true;

else isArray = false;

#ifdef DISPLAY

cout Constructing GCPtr. ;

if(isArray)

cout Size is arraySize endl;

else

cout endl; #endif

Конструктор GCPtr о позволяет создавать как инициализированные, так и Неинициализированные экземпляры. Если декларируется инициализированный объект, память, на которую он будет указывать, передается через



указатель t. В противном случае t равен null. Рассмотрим действие конструктора подробнее.

Сначала поле first равно true, т. е. создается первый объект типа GCPta:. Если это так, то функция shutdownO регистрируется как функция завершения с помощью вызова atexit о. Функция atexit о ИЗ стандартной библиотеки функций С++ регистрирует функцию, которая будет вызываться при завершении программы. Вызов функции shutdownO обеспечивает очистку любой памяти, которая к этому времени не была освобождена из-за циклических ссылок.

Далее выполняются просмотр списка gclist и попытка найти элемент, у которого адрес совпадает со значением указат18ля t. Если такой адрес найден, то связанный с ним счетчик ссылок увеличивается на единицу. Если нет элемента с адресом, совпадающим со значением t, новый объект типа GClnfo, содержащий этот адрес, создается и добавляется в список gclist.

Затем конструктор GCPtr () устанавливает в поле addr адрес, равный значению параметра t, и задает соответствующие значения полей isArray и arraySize. Помните, ЧТО если вы распределяете в памяти массив, то надо явно задать его размер при объявлении указателя типа GCPtr, который будет на него ссылаться. Если этого не сделать, то отведенная память не будет освобождаться должным образом, а в случае массивов из объектов класса будут некорректно вызываться деструкторы.

Деструктор класса GCPtr

Код деструктора для класса GCPtr приведен далее. Деструктор класса GCPtr. template <class Т, int size> GCPtr<T, size>::-GCPtr() {

list<GCInfo<T> >::iterator p;

p = findPtrlnfo(addr)7

if(p->refcount) p->refcount-; уменьшает на единицу счетчик ссылок

#ifdef DISPLAY

cout GCPtr going out of scope.\n ; #endif

Собирает мусор, когда указатель выходит за пределы области видимости, collect();



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

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