ЗАМЕЧАНИЕ
ЗАМЕЧАНИЕ
ЗАМЕЧАНИЕ
Чтобы использовать средства управления памятью 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++ существует два механизма для безопасного копирования и присваивания объектов классов, имеющих члены-указатели: почленная инициализация и почленное присваивание.