Язык программирования C++. Вводный курс

Оператор размещения new() и оператор delete()


Оператор-член new()

может быть перегружен при условии, что все объявления имеют разные списки параметров. Первый параметр должен иметь тип size_t:

class Screen {

public:

   void *operator new( size_t );

   void *operator new( size_t, Screen * );

   // ...

};



Остальные параметры инициализируются аргументами размещения, заданными при вызове new:

void func( Screen *start ) {

   Screen *ps = new (start) Screen;

   // ...

}

Та часть выражения, которая находится после ключевого слова new и заключена в круглые скобки, представляет аргументы размещения. В примере выше вызывается оператор new(), принимающий два параметра. Первый автоматически инициализируется значением, равным размеру класса Screen в байтах, а второй– значением аргумента размещения start.

Можно также перегружать и оператор-член delete(). Однако такой оператор никогда не вызывается из выражения delete. Перегруженный delete()

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

(это не опечатка, мы действительно имеем в виду new), возбуждает исключение. Рассмотрим использование delete()

более внимательно.

Последовательность действий при вычислении выражения

Screen *ps = new ( start ) Screen;

такова:

1.      Вызывается определенный в классе оператор new(size_t, Screen*).

2.      Вызывается конструктор по умолчанию класса Screen для инициализации созданного объекта.

Переменная ps

инициализируется адресом нового объекта Screen.

Предположим, что оператор класса new(size_t, Screen*) выделяет память с помощью глобального new(). Как разработчик может гарантировать, что память будет освобождена, если вызванный на шаге 2 конструктор возбуждает исключение? Чтобы защитить пользовательский код от утечки памяти, следует предоставить перегруженный оператор delete(), который вызывается только в подобной ситуации.

Если в классе имеется перегруженный оператор с параметрами, типы которых соответствуют типам параметров new(), то компилятор автоматически вызывает его для освобождения памяти. Предположим, есть следующее выражение с оператором размещения new:



Содержание раздела