logo
volkov / C++ / Бьерн Страуструп-Справочное руководство по С++

R.12.5 Свободная память

Когда создается объект с помощью операции new, для получения свободной

памяти вызывается (неявно) функция operator new() ($$R.5.3.3).

Если функция operator new() не может выполнить запрос, она

возвращает 0.

В классе X функция X::operator new() является статическим членом,

даже если она не описана явно как static. Первый ее параметр должен

иметь тип size_t, - зависящий от реализации целочисленный тип,

который определен в стандартном заголовочном файле <stddef.h>, и

она должна возвращать значение типа void*, например:

class X {

// ...

void* operator new(size_t);

void* operator new(size_t, Arena*);

};

Правила выбора подходящей функции operator new() обсуждаются

в $$R.5.3.3.

В классе X функция X::operator delete() является статическим

членом, даже если она не описана явно как static. Первый ее параметр

должен быть типа void* и можно добавлять второй параметр типа

size_t. Она не может возвращать какое-либо значение и тип

возвращаемого значения должен быть void, например:

class X {

// ...

void operator delete(void*);

};

class Y {

// ...

void operator delete(void*, size_t);

};

В каждом классе можно описать только одну функцию operator delete(),

значит эта функция не может быть перегруженной. Глобальная функция

operator delete() имеет единственный параметр типа void*.

Если функция описана с двумя формальными параметрами, она вызывается

с двумя параметрами, второй из которых показывает размер удаляемого

объекта. Передаваемый размер определяется с помощью деструктора

(если он есть) или по типу (статическому) указателя на удаляемый

объект. Операция пройдет корректно, если тип указателя, заданного

как фактический параметр, будет совпадать с типом объекта (а не будет,

к примеру, просто типом указателя на базовый класс) или, если

этот тип является типом указателя на базовый класс с виртуальным

деструктором.

Для массивов объектов типа класс используются глобальные функции

operator new() и operator delete() ($$R.5.3.3, $$R.5.3.4).

Поскольку функции X::operator new() и X::operator delete()

статические, они не могут быть виртуальными. Функция

operator delete(), которая вызывается из деструктора для освобождения

памяти, выбирается по обычным правилам областей видимости,

например:

struct B {

virtual ~B();

void* operator new(size_t);

void operator delete(void*);

};

struct D : B {

~D();

void* operator new(size_t);

void operator delete(void*);

};

void f()

{

B* p = new D;

delete p;

}

В этом примере память для объекта класса D выделяется с помощью

D::operator new(), а благодаря наличию виртуального деструктора,

освобождается с помощью D::operator delete().