Тип 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

#include

#include

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);

  void *operator new[](size_t size);

  void operator delete(void *p);

  void operator delete[](void *p);

  void show();

};

// Перегрузка оператора new для класса three_d.

void *three_d::operator new(size_t size)

{

 void *p;

 cout <<"Выделение памяти для объекта класса three_d.\n";

 р = malloc(size);

 // Генерирование исключения в случае неудачного выделения памяти.

 if(!р) {

  bad_alloc ba;

  throw ba;

 }

 return р;

}

// Перегрузка оператора new для массива объектов типа three_d.

void *three_d::operator new[](size_t size)

{

 void *p;

 cout <<"Выделение памяти для массива three_d-oбъeктoв.";

 cout << "\n";

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги