Screen *ps = new (start) Screen;
Если конструктор по умолчанию класса Screen возбуждает исключение, то компилятор ищет delete() в области видимости Screen. Чтобы такой оператор был найден, типы его параметров должны соответствовать типам параметров вызванного new(). Поскольку первый параметр new() всегда имеет тип size_t, а оператора delete() – void*, то первые параметры при сравнении не учитываются. Компилятор ищет в классе Screen оператор delete() следующего вида:
void operator delete( void*, Screen* );
Если такой оператор будет найден, то он вызывается для освобождения памяти в случае, когда new() возбуждает исключение. (Иначе – не вызывается.)
Разработчик класса принимает решение, предоставлять ли delete(), соответствующий некоторому new(), в зависимости от того, выделяет ли этот оператор new() память самостоятельно или пользуется уже выделенной. В первом случае delete() необходимо включить для освобождения памяти, если конструктор возбудит исключение; иначе в нем нет необходимости.
Можно также перегрузить оператор размещения new[]() и оператор delete[]() для массивов:
class Screen {
public:
void *operator new[]( size_t );
void *operator new[]( size_t, Screen* );
void operator delete[]( void*, size_t );
void operator delete[]( void*, Screen* );
// ...
};
Оператор new[]() используется в случае, когда в выражении, содержащем new для распределения массива, заданы соответствующие аргументы размещения:
void func( Screen *start ) {
// вызывается Screen::operator new[]( size_t, Screen* )
Screen *ps = new (start) Screen[10];
// ...
}
Если при работе оператора new конструктор возбуждает исключение, то автоматически вызывается соответствующий delete[]().
Упражнение 15.9
Объясните, какие из приведенных инициализаций ошибочны:
class iStack {
public:
iStack( int capacity )
: _stack( capacity ), _top( 0 ) {}
// ...
private:
int _top;
vatcor< int > _stack;
};
(a) iStack *ps = new iStack(20);
(b) iStack *ps2 = new const iStack(15);
(c) iStack *ps3 = new iStack[ 100 ];
Упражнение 15.10
Что происходит в следующих выражениях, содержащих new и delete?
class Exercise {
public:
Exercise();
~Exercise();
};
Exercise *pe = new Exercise[20];
delete[] ps;
Измените эти выражения так, чтобы вызывались глобальные операторы new() и delete().
Упражнение 15.11
Объясните, зачем разработчик класса должен предоставлять оператор delete().