|
|
|
| |
Главная С++ (часть 3) Эффект выхода объекта GCPtr за пределы области видимости до ее завершения
Эффект выхода объекта GCPtr за пределы области видимости до ее завершения |
В листинге 2.3 приводится пример программы, демонстрирующий эффект выхода объекта GCPtr за пределы области видимости до ее завершения. ГП^5------------------------------------------------------------------------------------------------------------------------------------J Листинг 2.3. Более интересный пример // Показывает выход объекта GCPtr за пределы области видимости 11 До завершения программы, ¦include <iostream> ¦include <new> ¦include "gc.h" Using namespace std; int main() ( GCPtr<int> p; GCPtr<int> q; try { p = new int(10); q = new int(11); cout « "Value at p is: " « *p « endl; cout « "Value at q is: " « *q « endl; cout « "Before entering block.\n"; // Теперь создадим локальный объект. { // Начало блока. GCPtr<int> г = new int(12); cout « "Value at r is: " « *r « endl; } // Конец блока, вызывающий выход г за пределы области видимости. cout « "After exiting block.\n"; } catch(bad_alloc exc) { cout « "Allocation failure!\n"; return 1; } cout « "Done\n"; return 0; } Если включен режим отображения, приведенная программа выводит на экран следующую информацию. Constructing GCPtr. Constructing GCPtr. Value at p is: 10 Value at q is: 11 Before entering block. Constructing GCPtr. Value at r is: 12 GCPtr going out of scope. Before garbage collection for gclist<inc, 0>: memPtr refcount value [002F31D8] 0 12 [002F12FO] 1 11 [002F12CO] 1 10 [00000000] 0 Deleting: 12 After garbage collection for gclist<int, 0>: memPtr refcount value [002F12FO] 1 11 [002F12CO] 1 10 After exiting block. Done GCPtr going out of scope. Before garbage collection for gclist<int, 0>: memPtr refcount value [002F12FO] 0 11 [002F12C0] 1 10 Deleting: 11 After garbage collection for gclist<int, 0>: roemPtr refcount value [002F12C0] 1 10 GCPtr going out of scope. Before garbage collection for gclist<int, 0>: ""emPtr refcount value 1002F12CO] 0 10 dieting: 10 After garbage collection for gclist<int, 0>: ""^tr refcount value — Empty — Обсудим подробно приведенные код программы и результаты ее выполнения. Прежде всего, отметим, что объекты р и q создаются при запуске main (), а объект г не создается до тех пор, пока не начнет выполняться его блок. Как вы знаете, в языке С++ локальные переменные не создаются до выполнения блока, в котором они объявлены. В момент создания объекта г памяти, на которую он указывает, присваивается начальное значение 12. Это значение выводится на экран, и блок заканчивается. Его завершение вызывает выход объекта г за пределы области видимости, что влечет за собой вызов его деструктора, который уменьшает до нуля счетчик ссылок, хранящийся в списке gclist и связанный с объектом г. Далее вызывается функция collect о для сбора мусора. Поскольку включен режим отображения, после запуска функции collect о на экран выводится содержимое списка gclist. В нем четыре элемента. Первый из них — тот, который прежде был связан с объектом г. Обратите внимание, что его счетчик ссылок (поле refcount) равен нулю, указывая на то, что фрагмент памяти, адрес которого хранится в поле memPtr, больше не используется ни одним программным элементом. Следующие 2 элемента еще активны и связаны с объектами q и р соответственно. Так как эти элементы — действующие, память, на которую они указывают, пока еще не освобождается. Последний элемент списка представляет неопределенный или пустой адрес (null pointer), на который ссылались объекты р и q в момент их создания. В данный момент он уже не используется и будет удален из списка функцией collect о (конечно, при этом никакая память не освобождается). Память, ранее связанная с объектом г, очищается, так как нет других объектов типа GCPtr, указывающих на нее, что и подтверждается строкой на экране: "Deleting: 12 " (уничтожается 12). После того как это сделано, часть программы, расположенная после блока, продолжает выполняться. В конце, когда программа завершает работу, объекты р и q выходят за пределы области видимости, и память, на которую они указывают, освобождается. В данном случае деструктор объекта q вызывается первым, свидетельствуя о том, что сначала сборщик мусора обрабатывает этот объект. Затем уничтожается объект р и выводится на экран пустой список gclist.
|
|
|
|
|