Как вызвать версию удаления nothrow? - PullRequest
12 голосов
/ 23 октября 2010

У меня есть следующий код, который не компилируется:

int *p = new(nothrow) int;
delete (nothrow) p; //Error

Я получаю ошибку:

ошибка C2440: «delete»: невозможно преобразовать из «const std :: nothrow_t 'to' void * '

Существует ли nothrow версия delete?Если да, то как я могу вызвать его?


В C ++: Полная ссылка, он существует, но я видел разные мнения в Интернете, отсюда и путаница.

MSDN также говорит о его существовании, но я не мог найти, как его можно использовать в коде.

Здесь , некоторые люди говорят, что такого не существует.

Ответы [ 3 ]

16 голосов
/ 23 октября 2010

A std::nothrow_t функция освобождения существует, но вы не можете вызвать ее с выражением delete.

Функция освобождения существует для полноты. Если выражение new завершается неудачно из-за исключения, компилятору необходимо освободить память, выделенную ему через operator new, с соответствующим вызовом operator delete. Таким образом, должен быть operator delete, который принимает std::nothrow_t, чтобы разрешить это.

(То есть, как правило, выражение new с формой new (args...) T выделит память при вызове operator new(sizeof(T), args...). «Сопоставить» означает вызвать operator delete с теми же аргументами, кроме первого .)

Обратите внимание, что вы можете позвонить оператору напрямую: operator delete(memory, std::nothrow);. Однако выражение delete никогда не вызывает глобальную функцию освобождения с дополнительными параметрами.


Так что вы можете «позвонить» с помощью:

struct always_throw
{
    always_throw() { throw std::exception(); }
};

new (std::nothrow) always_throw;

В какой-то момент это выделит память при вызове:

void* __memory = operator new(sizeof(always_throw), std::nothrow);

Поскольку инициализация объекта вызывает, компилятору необходимо освободить выделенную память с помощью соответствующей функции освобождения, поэтому он делает:

operator delete(__memory, std::nothrow);

Вызов std::nothrow_t версии.

5 голосов
/ 23 октября 2010

Нет такой формы delete, потому что delete не бросает, так как:

  1. Не выполняет выделений.
  2. Часто используется в деструкторах, которые не должны бросать!

Элементы, созданные с новой версией nothrow, будут возвращать NULL вместо того, чтобы выдавать исключение bad_alloc. Использование delete для NULL совершенно допустимо, поэтому нет ситуации, когда он должен бросать.

2 голосов
/ 23 октября 2010

Для большинства практических целей существует только одна версия удаления.new(nothrow) записывается как новый оператор размещения, но по большей части соответствующей версии для удаления нет.Единственное исключение из этого - версия удаления, которая вызывается, когда новые броски размещения - но так как (в этом случае) вы уверены, что new не может бросить, эта версия удаления не имеет реального использования/ Помощь здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...