void *operator new(size_t size)
{
/* В случае невозможности выделить память генерируется исключение типа bad_alloc. Конструктор вызывается автоматически. */
return pointer_to_memory;
}
// Удаление объекта.
void operator delete(void *p)
{
/* Освобождается память, адресуемая указателем р. Деструктор вызывается автоматически. */
}
Тип size_t специально определен, чтобы обеспечить хранение размера максимально возможной области памяти, которая может быть выделена для объекта. (Тип size_t, по сути, —это целочисленный тип без знака.) Параметр size определяет количество байтов памяти, необходимых для хранения объекта, для которого выделяется память. Другими словами, это объем памяти, который должна выделить ваша версия оператора new. Перегруженная функция new должна возвращать указатель на выделяемую ею память или генерировать исключение типа bad_alloc в случае возникновении ошибки. Помимо этих ограничений, перегруженная функция new может выполнять любые нужные действия. При выделении памяти для объекта с помощью оператора new (его исходной версии или вашей собственной) автоматически вызывается конструктор объекта.
Функция delete получает указатель на область памяти, которую необходимо освободить. Затем она должна вернуть эту область памяти системе. При удалении объекта автоматически вызывается его деструктор.
Чтобы выделить память для массива объектов, а затем освободить ее, необходимо использовать следующие форматы операторов new и delete.
// Выделение памяти для массива объектов.
void *operator new[](size_t size)
{
/* В случае невозможности выделить память генерируется исключение типа bad_alloc. Каждый конструктор вызывается автоматически. */
return pointer_to_memory;
}
// Удаление массива объектов.
void operator delete[](void *p)
{
/* Освобождается память, адресуемая указателем р. При этом автоматически вызывается деструктор для каждого элемента массива. */
}
При выделении памяти для массива автоматически вызывается конструктор каждого объекта, а при освобождении массива автоматически вызывается деструктор каждого объекта. Это значит, что для выполнения этих действий не нужно явным образом программировать их.
Операторы new и delete, как правило, перегружаются относительно класса. Ради простоты в следующем примере используется не новая схема распределения памяти, а перегруженные функции new и delete, которые просто вызывают С-ориентированные функции выделения памяти malloc() и free(). (В своем собственном приложении вы вольны реализовать любой метод выделения памяти.)
Чтобы перегрузить операторы new и delete для конкретного класса, достаточно сделать эти перегруженные операторные функции членами этого класса. В следующем примере программы операторы new и delete перегружаются для класса three_d. Эта перегрузка позволяет выделить память для объектов и массивов объектов, а затем освободить ее.
// Демонстрация перегруженных операторов new и delete.
#include <iostream>
#include <new>
#include <cstdlib>
using namespace std;
class three_d {
int x, y, z; // 3-мерные координаты
public:
three_d() {
x = у = z = 0;
cout << "Создание объекта 0, 0, 0\n";
}
three_d(int i, int j, int k) {
x = i;
у = j;
z = k;
cout << "Создание объекта " << i << ", ";
cout << j << ", " << k;
cout << '\n';
}
~three_d() { cout << "Разрушение объекта\n"; }
void *operator new(size_t size);