Почему в C ++ нет выражения удаления размещения? - PullRequest
30 голосов
/ 02 мая 2011

Почему в C ++ нет удаления размещения, которое непосредственно соответствует новому размещению, то есть вызывает деструктор и вызывает соответствующий оператор удаления размещения?

Например:

MyType *p = new(arena) MyType;
...
//current technique
p->~MyType();
operator delete(p, arena);

//proposed technique
delete(arena) p;

Ответы [ 5 ]

22 голосов
/ 02 января 2013

operator delete уникален тем, что является функцией, не являющейся членом или статической, которая отправляется динамически.Тип с виртуальным деструктором выполняет вызов своего собственного delete из самого производного деструктора.

struct abc {
    virtual ~abc() = 0;
};

struct d : abc {
    operator delete() { std::cout << "goodbye\n"; }
};

int main() {
    abc *p = new d;
    delete p;
}

( Запустите этот пример .)

Для этогочтобы работать с удалением размещения, деструктор должен каким-то образом передать дополнительные аргументы operator delete.

  • Решение 1: Передать аргументы через виртуальную функцию.Для этого требуется отдельный виртуальный деструктор для каждого статического члена и глобальная перегрузка operator delete с различными аргументами.
  • Решение 2: Пусть виртуальный деструктор возвращает указатель на функцию для вызывающей стороны, указывающую, что operator delete должен быть назван.Но если деструктор выполняет поиск, это сталкивается с той же проблемой, связанной с требованием нескольких определений виртуальных функций, что и # 1.Должен быть создан некоторый набор абстрактных перегрузок, который разрешит вызывающая сторона.

У вас есть отличная точка зрения, и это было бы хорошим дополнением к языку.Теоретически, возможно, вписать его в существующую семантику delete.Но большую часть времени мы не используем полную функциональность delete, и достаточно использовать вызов псевдодеструктора, за которым следует что-то вроде arena.release(p).

21 голосов
/ 02 мая 2011

Потому что в этом нет необходимости, поскольку у нас уже есть ptr->~type();

8 голосов
/ 02 мая 2011

Возможно, потому что был синтаксис для явного вызова деструктора без освобождения (в точности как в вашем вопросе), но не было синтаксиса для явного конструирования в необработанной памяти?

7 голосов
/ 09 июля 2012

На самом деле существует удаление размещения, которое вызывается реализацией для объекта, который был «выделен» с использованием размещения new, если конструктор выдал исключение.*

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

2 голосов
/ 02 мая 2011

Весь смысл размещения нового состоит в том, чтобы отделить создание объекта от управления его памятью.Поэтому нет смысла связывать его во время уничтожения объекта.
Если память для ваших объектов из кучи и вы хотите одинаковое время жизни для объектов и их памяти, просто используйте operator new и operator delete, возможно, переопределите их, если хотителюбое специальное поведение.
Размещение new хорошо, например, в векторе, который сохраняет большой кусок сырой памяти и создает и уничтожает объект внутри него, но без освобождения памяти.

...