Если предположить, что Buffer::operator delete
не существует, верная версия delete buf;
выполнит всю необходимую очистку. Чтобы быть немного безопаснее, вы можете сказать ::delete buf;
.
Ниже следует материал для обсуждения языка адвоката.
5.3.5 / 1
Оператор delete-expression уничтожает наиболее производный объект (1.8) или массив, созданный с помощью new-expression .
Ненужное-выражение:
::
opt delete
cast-expression
::
opt delete [ ]
cast-expression
Первый вариант - для объектов, не являющихся массивами, а второй - для массивов. ...
5.3.5 / 2
... В первой альтернативе ( удалить объект ) значение операнда delete
может быть нулевым указателем, указателем на объект, не являющийся массивом, созданный предыдущим new-expression , или указатель на подобъект (1.8), представляющий базовый класс такого объекта (раздел 10). Если нет, поведение не определено.
Таким образом, указатель должен указывать на объект, созданный с помощью new-expression , которое определено:
5.3.4 / 1
новое выражение:
::
opt new
новое размещение opt новый тип -id _new-initializer_ opt
::
opt new
новое размещение opt (
идентификатор типа )
новый инициализатор opt
новое размещение:
Таким образом, "размещение нового" считается новым выражением . Ничто не запрещает delete-expression там.
Кроме того, получается, что delete-expression делает абсолютно правильные вещи для очистки объекта, несмотря на пользовательское создание.
* +1136 * 5.3.5 / 6-9 * * 1 137
Если значение операнда delete-expression не является нулевым значением указателя, delete-expression вызовет деструктор (если таковой имеется) для объекта или элементы массива удаляются. ...
Если значение операнда выражения удаления не является нулевым значением указателя, delete-выражение вызовет функцию освобождения (3.7 .4.2). В противном случае не определено, будет ли вызвана функция освобождения. [ Примечание: Функция освобождения вызывается независимо от того, выбрасывает ли деструктор для объекта или некоторого элемента массива исключение. - конечная нота ]
Когда ключевому слову delete
в delete-expression предшествует унарный оператор ::
, для освобождения хранилища используется глобальная функция освобождения.
Итак, ::delete buf;
полностью эквивалентно:
try {
buf->~Buffer();
} catch(...) {
::operator delete(mem);
throw;
}