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



Pdf көрінісі
бет253/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   248   249   250   251   252   253   254   255   256
Байланысты:
Бьерн Страуструп. Язык программирования С . М Бином, 2011

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
әкімшілігінің қараңыз

    Басты бет