C++.Бархатный путь


Функции operator new() и operator delete() - часть 4


/* Встроенная операторная функция operator new() */ void *operator new(size_t size) { cout << "Это void *operator new(" << size << ")" << endl; return NULL; }

Новая операторная функция даже не пытается использовать операцию выделения памяти. Она возвращает пустое значение указателя. При этом значением выражения размещения в операторе xPoint = new TypeX;

оказывается нулевой адрес. И в результате запуск конструктора отменяется:

Это void *operator new(1) OK

Аналогичным образом работает программный код, который обеспечивает вызов деструктора: непосредственно перед запуском деструктора производится проверка значения указателя.

Мы возвращаем операторную функцию к исходному состоянию, после чего подвергнем исходную программу небольшой модификации. Расположим непосредственно перед символами операций new и delete (символ операции не обязательно представляет операцию!) разделители :: (именно разделители, поскольку они служат для модификации операции, а не используются в сочетании с операндами).

#include <iostream.h> #include "TypeX.h" void main() { TypeX *xPoint = NULL; xPoint = ::new TypeX; ::delete xPoint; cout << "OK" << endl; }

В результате выполнения новой версии нашей программы мы получаем следующий результат:

Это TypeX() Это ~TypeX() OK

Операторные функции не вызываются, однако память выделяется и производится запуск конструктора, а затем и деструктора.

Это означает, что помеченные разделителем :: выражения размещения и освобождения исправно работают, выделяя и освобождая необходимую память. Символы операций ::new и ::delete воспринимаются транслятором как символы собственных "глобальных" операций выделения и освобождения памяти языка C++.

К аналогичному результату мы приходим, исключив из объявления класса TypeX объявления операторных функций operator new() и operator delete(). В этом случае перед символами операций new и delete даже не требуется располагать разделители. В этом случае транслятор их однозначно воспринимает как символы операций.

Мы снова восстанавливаем файл с объявлением класса TypeX и очередной раз модифицируем нашу программу. На этот раз мы заменим выражения размещения и освобождения выражениями явного вызова операторных функций.

#include <iostream.h> #include "TypeX.h" void main() { TypeX *xPoint = NULL; xPoint = (TypeX *) TypeX::operator new (sizeof(TypeX)); TypeX::operator delete(xPoint, sizeof(TypeX)); // delete xPoint; cout << "OK" << endl; }

В результате выполнения этой версии программы на дисплей будут выведены следующие сообщения:

Это void *operator new(1) Это void operator delete(1) OK

Операторные функции работают успешно, память выделяется и освобождается, однако управление конструктору и деструктору не передаётся. Выражение вызова операторных функций operator new() и operator delete() не обеспечивают вызова конструктора и деструктора. Мы уже знаем, что в C++, за исключением весьма странного выражения явного вызова, вызов конструктора и деструктора обеспечивается транслятором в контексте ограниченного множества выражений. Нет соответствующего выражения, - нет и вызова конструктора.

| |

 




- Начало -  - Назад -  - Вперед -