Как я могу назвать оригинальный "оператор new", если я его перегрузил?
Предположим, мне нужно перегрузить глобальный ::operator new()
для хранения дополнительных данных с каждым выделенным объектом. Таким образом, в основном это будет работать следующим образом:
- для каждого вызова глобального
::operator new()
он примет переданный размер объекта и добавит размер дополнительных данных
- он выделит блок памяти размера, выведенный на предыдущем шаге
- он будет смещать указатель на часть блока, не занятую дополнительными данными, и вернуть это значение смещения вызывающему абоненту
::operator delete()
сделает то же самое в обратном направлении - сдвиг указателя, доступ к дополнительным данным, освобождение памяти.
Теперь вопрос в том, как распределить память? Конечно, я могу назвать malloc()
или какую-то определенную платформой функцию (как это обычно делается). Но обычно, когда мне нужно выделить необработанную память в С++, я вызываю ::operator new()
. Могу ли я вызвать исходный ::operator new()
для выделения памяти из моего перегруженного глобального ::operator new()
?
Ответы
Ответ 1
Вы не можете получить к ним доступ, потому что это не перегрузка, это замена. Когда вы определяете свой собственный ::operator new
, старый уходит. Это в значительной степени.
По существу, вам нужно вызвать malloc
из пользовательского ::operator new
. Не только это, но и следуйте указаниям в 18.4.1.1/4, чтобы правильно обрабатывать ошибки:
Поведение по умолчанию:
- Выполняет цикл: Внутри цикла функция сначала попытки выделить запрошенные место хранения. Является ли попытка вызов стандартной библиотеки C Функция malloc не указана.
- Возвращает указатель на выделенную если попытка выполнена успешно. В противном случае, если последний аргумент set_new_handler() был нулевым указателем, throw bad_alloc.
- В противном случае функция вызывает текущий new_handler (18.4.2.2). Если вызываемая функция возвращается, цикл повторяется.
- Цикл прекращается, когда попытка выделить запрошенное хранилище выполнено успешно или когда вызываемая функция new_handler не возвращается.