Главная arrow С++ (часть 3) arrow Функция shutdown

Функция shutdown

Если в программе объектом GCPtr создается циклическая ссылка, то по завершении приложения остаются размещенные в динамической памяти объекты, которые должны быть удалены. Это важно, потому что они могут иметь деструкторы, которые следует вызвать в программе. Функция shutdown о решает эту задачу. Эта функция регистрируется функцией atexito, когда создается первый объект класса GCPtr, как описывалось ранее. Это означает, что она будет вызвана, когда программа завершает свою работу. Далее приведен код функции shutdowno.
// Очищает gclist, когда программа завершается, template <class T, int size> void GCPtr<T, size>::shutdown()  {
if (gclistSizeO == 0) return; // список пуст
list<GCInfo<T> >::iterator p;
for(p = gclist.begin(); p != gclist.end(); p++)  {
// Устанавливает все счетчики ссылок в ноль. p->refcount = 0;
}
ttifdef DISPLAY
cout « "Before collecting for shutdown() for " « typeid(T).name() « "\n";
ttendif
collect();
ttifdef DISPLAY
cout « "After collecting for shutdown() for " « typeid(T).name() « "\n";
#endif
}
Сначала, если список пуст, как и должно быть, функция shutdown о просто обеспечивает возврат в вызывающую программу. В противном случае она присваивает нулевые значения счетчикам ссылок элементов, до сих пор остающихся в списке gclist, и затем вызывает функцию collect о. Напоминаю, что функция collect о уничтожает любой объект, у которого значение счетчика ссылок равно нулю. Таким образом, присваивание нулевых значений счетчикам ссылок гарантирует уничтожение всех размещенных ранее объектов.
Класс GClnfo
Информационный список для сбора мусора, хранящийся в объекте gclist, содержит элементы типа Gcinf о. Описание класса Gcmf о приведено далее.
// Этот класс определяет элемент, который запоминается //в информационном списке сбора мусора.
//
teBplate <class T> class GCInfo { public:
unsigned refcount; // текущий счетчик ссылок T *memPtr; // указатель на выделенную память
/* isArray равен true, если memPtr указывает на
распределенный массив.
В противном случае false. */ bool isArray; // true, если указание на массив
/* Если memPtr указывает на распределенный
массив, то arraySize содержит его размер */ unsigned arraySize; // длина или размер массива
// Здесь mPtr указывает на выделенную память.
// Если это массив, в size указывается
// размер массива.
GCInfo (Т *mPtr, unsigned size=0)  {
refcount - 1;
memPtr = mPtr;
if(size != 0) isArray = true;
else
isArray = false; arraySize = size;
}
};
Как упоминалось ранее, каждый объект Gcmf о содержит указатель на выделенную память в поле memPtr и счетчик ссылок, связанный с этим фрагментом памяти, — в поле refcount. Если память, на которую указывает содержимое поля memPtr, хранит массив, следует указать его длину при создании объекта Gcinfo. В этом случае поле isArray устанавливается равным true, а размер массива сохраняется в поле arraySize.
Объекты класса Gcmfo помещаются в список стандартного типа list из библиотеки STL. Для того чтобы обеспечить поиск элементов в этом списке, необходимо определить перегруженную операцию operator== (), код которой приведен далее.
// Перегруженная операция == позволяет сравнивать объекты GClnfo. // Это необходимо для класса list библиотеки STL. template <class T> bool operator==(const GCInfo<T> &obl, const GCInfo<T> &ob2)  ( return (obi.memPtr == ob2.memPtr);
}
Два объекта равны, только если идентичны их поля memPtr. Используемый вами компилятор может потребовать перегрузки других операций для сохранения объектов GClnfo в списке класса list из библиотеки STL.