Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет253/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   248   249   250   251   252   253   254   255   256
13.10.1 Сборщик мусора 
Сборку мусора можно рассматривать как моделирование бесконечной памяти на памяти ограниченного 
размера. Помня об этом, можно ответить на типичный вопрос: должен ли сборщик мусора вызывать 
деструктор для тех объектов, память которых он использует? Правильный ответ - нет, поскольку, если 
размещенный в свободной памяти объект не был удален, то он не будет и уничтожен. Исходя из этого, 
операцию delete можно рассматривать как запрос на вызов деструктора (и еще это - сообщение 
системе, что память объекта можно использовать). Но как быть, если действительно требуется 
уничтожить размещенный в свободной памяти объект, который не был удален? Заметим, что для 
статических и автоматических объектов такой вопрос не встает, - деструкторы для них неявно 
вызываются всегда. Далее, уничтожение объекта "во время сборки мусора" по сути является операцией 
с непредсказуемым результатом. Она может совершиться в любое время между последним 
использованием объекта и "концом программы", а значит, в каком состоянии будет программа в этот 
момент неизвестно. Здесь использованы кавычки, потому что трудно точно определить, что такое конец 
программы. (прим. перев.) 
Трудно правильно запрограммировать такие операции и они не так полезны, как кажется. 
Задачу уничтожения объектов, если время этой операции точно не задано, можно решить с помощью 
программы обслуживания заявок на уничтожение. Назовем ее сервером заявок. Если объект 
необходимо уничтожить в конце программы, то надо записать в глобальный ассоциативный массив его 
адрес и указатель на функцию "очистки". Если объект удален явной операцией, заявка аннулируется. 
При уничтожении самого сервера (в конце программы) вызываются функции очистки для всех 
оставшихся заявок. Это решение подходит и для сборки мусора, поскольку мы рассматриваем ее как 
моделирование бесконечной памяти. Для сборщика мусора нужно выбрать одно из двух решений: либо 
удалять объект, когда единственной оставшейся ссылкой на него будет ссылка, находящаяся в массиве 
самого сервера, либо (стандартное решение) не удалять объект до конца программы, поскольку все-
таки ссылка на него есть. 
Сервер заявок можно реализовать как ассоциативный массив ($$8.8): 
class Register { 
Map m; 
public: 
insert(void* po, void(*pf)()) { m[po]=pf; } 
remove(void* po) { m.remove(po); } 
}; 
Register cleanup_register; 


Бьерн Страуструп.
Язык программирования С++ 
 
363 
Класс, постоянно обращающийся к серверу, может выглядеть так: 
class X { 
// 
... 
static void cleanup(void*); 
public: 
X() 

cleanup_register.insert(this,&cleanup); 
// 
... 

~X() { cleanup(this); } 
// 
... 
}; 
void X::cleanup(void* pv) 

X* px = (X*)pv; 
cleanup_register.remove(pv); 
// очистка 

Чтобы в классе Register не иметь дела с типами, мы использовали статическую функцию-член с 
указателем типа void*. 


Достарыңызбен бөлісу:
1   ...   248   249   250   251   252   253   254   255   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет