Читать «Справочное руководство по C++» онлайн - страница 70
Бьярн Страустрап
void f(X* p);
static char buf[sizeof(X)];
void g() // редкий, специальный случай
{
X* p = new(buf) X(222); // размещение в buf[] и инициализация
f(p);
p-›X::~X(); // удаление
}
Обозначения, использованные для явного вызова деструктора, можно использовать для имени любого простого типа, например,
int* p;
//…
p-›int::~int();
Использование такой записи для типа, у которого нет деструктора, проходит бесследно. Допуская такую запись, мы разрешаем пользователям писать программу, не задумываясь над тем, есть ли данного типа деструктор.
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);