Бьерн Страуструп.
Язык программирования С++
147
static
name*
nfree;
};
Функции name::operator new() и name::operator delete() будут использоваться (неявно) вместо
глобальных функций operator new() и operator delete(). Программист может для конкретного типа
написать более эффективные по времени и памяти функции размещения и удаления, чем
универсальные функции operator new() и operator delete(). Можно, например, разместить заранее "куски"
памяти, достаточной для объектов типа name, и связать их в список; тогда операции размещения и
удаления сводятся к простым операциям со списком. Переменная nfree используется как начало списка
неиспользованных кусков памяти:
void* name::operator new(size_t)
{
register name* p = nfree; //
сначала выделить
if
(p)
nfree
=
p->next;
else { // выделить и связать в список
name* q = (name*) new char[NALL*sizeof(name) ];
for (p=nfree=&q[NALL-1]; q
next = p-1;
(p+1)->next
=
0;
}
return
p;
}
Распределитель памяти, вызываемый new, хранит вместе с объектом его размер, чтобы операция
delete выполнялась правильно. Этого дополнительного расхода памяти можно легко избежать, если
использовать распределитель, рассчитанный на конкретный тип. Так, на машине автора функция
name::operator new() для хранения объекта name использует 16 байтов, тогда как стандартная
глобальная функция operator new() использует 20 байтов.
Отметим, что в самой функции name::operator new() память нельзя выделять таким простым способом:
name* q= new name[NALL];
Это вызовет бесконечную рекурсию, т.к. new будет вызывать name::name().
Освобождение памяти обычно тривиально:
void name::operator delete(void* p, size_t)
{
((name*)p)->next = nfree;
nfree = (name*) p;
}
Приведение параметра типа void* к типу name* необходимо, поскольку функция освобождения
вызывается после уничтожения объекта, так что больше нет реального объекта типа name, а есть
только кусок памяти размером sizeof(name). Параметры типа size_t в приведенных функциях
name::operator new() и name::operator delete() не использовались. Как можно их использовать, будет
показано в $$6.7. Отметим, что наши функции размещения и удаления используются только для
объектов типа name, но не для массивов names.
Достарыңызбен бөлісу: