ЗАМЕЧАНИЕ

ЗАМЕЧАНИЕ

ЗАМЕЧАНИЕ

Чтобы использовать средства управления памятью C + + для выделения пространства в куче для объектов, в которых перетружен оператор new, поставьте перед оператором двойное двоеточие. Например, и строке

BNew *х = ::new BrandNew игнорируется перегруженный в объектах класса BNew оператор new. Аналогично, ::delete служит для обращения к оператору delete, используемому по умолчанию.

Установка обработчика ошибок оператора new

Обычно, если new не может выполнить запрос выделения памяти, оператор возвращает null.

Для того что­бы изменить действия, предпринимаемые по умолчанию в этом случае, в C++ следует присвоить адрес функ­ции-обработчика ошибок указателю _new__handler, определенному следующим образом:

typedef void (*vfp)(void);

vfp _new_handler;

Использование typedef не обязательно, но оно облегчает чтение объявления. Функция-обработчик ошибок ничего не возвращает и не имеет аргументов, она устанавливается с помощью вызова функции set_new_handler(), прототип которой содержится в файле NEW.H:

vfp set_new_handler(vfp);

Обработчик ошибок реализуется так же, как и обычная функция C++. Например, вы можете аварийно за­вершить программу с сообщением об ошибке нехватки памяти:

void memerr(void)

{

fputs("\n\nOut of memory\n", stderr);

exit(1);

}

Для того чтобы функция memerrO вызывалась в случае возникновения ошибок, связанных с нехваткой па­мяти, передайте адрес memerr функции set_new_handler() следующим образом;

set_new_handler(memerr);

Смотри также описание set_jiew_handler() в книге Освоение Borland C++. Энциклопедия функций.

Копирование объектов классов

Когда один объект класса копируется в другой объект совместимого типа, могут получиться самые неожи­данные результаты, в особенности это касается классов, в которых объявлены члены-указатели на данные. Обратите внимание на следующие четыре опасные ситуации.

• Когда один объект используется при объявлении нового объекта этого же класса для его инициализации.

• Когда объект передается функции параметром типа класса по значению.

• Когда функция возвращает объект класса (но не ссылку или указатель на объект).

• Когда в операторе один объект присваивается другому.

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

Имейте в виду, что существует разница между копированием объекта и присваиванием одного объекта другому, В первых трех случаях объекты создаются с помощью вызова конструктора, в четвертом — присваивание одного объекта другому не создает нового объекта и, следовательно, не приводит к вызову конструктора.

После копирования объекта может показаться, что все в порядке, однако, если объект класса содержит члены-указатели на данные, могут возникнуть неприятности. Копирование подобных объектов может привести к появлению указателей, ссылающихся на одно и то же место в памяти. Удаление одного из таких указателей приведет к тому, что другие указатели будут ссылаться на освобожденный участок памяти. Еще более печаль­но то, что удаление одного и того же участка памяти более одного раза в деструкторе класса может привести к разрушению кучи.

 

В C++ существует два механизма для безопасного копирования и присваивания объектов классов, имею­щих члены-указатели: почленная инициализация и почленное присваивание.