Почему в С++ нет выражения удаления места размещения?
Почему С++ не удаляет место размещения, которое напрямую соответствует новому месту размещения, т.е. вызывает деструктор и вызывает соответствующий оператор удаления места размещения?
Например:
MyType *p = new(arena) MyType;
...
//current technique
p->~MyType();
operator delete(p, arena);
//proposed technique
delete(arena) p;
Ответы
Ответ 1
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)
.
Ответ 2
Потому что нет необходимости, поскольку у нас уже есть ptr->~type();
Ответ 3
Возможно, потому, что существует синтаксис для явного вызова деструктора без освобождения (точно так же, как в вашем вопросе), но нет синтаксиса для явной конструкции в необработанной памяти?
Ответ 4
На самом деле существует удаление места размещения, которое вызывается реализацией для объекта, который был "выделен" с использованием размещения new, если конструктор создал исключение.
Из Википедии.
Функции удаления места размещения вызывается из новых выражений размещения. В частности, они вызываются, если конструктор объекта выдает исключение. В таких обстоятельствах, чтобы гарантировать, что программа не несет утечки памяти, вызывается функция удаления места размещения.
Ответ 5
Весь смысл размещения new - отделить создание объекта от управления памятью. Поэтому нет смысла связывать его во время уничтожения объекта.
Если память для ваших объектов находится в куче, и вы хотите, чтобы одно и то же время жизни для объектов и их памяти использовало только operator new
и operator delete
, возможно, переопределяя их, если вы хотите какого-либо особого поведения.
Размещение нового хорошо, например, в векторе, который хранит большой фрагмент необработанной памяти и создает и уничтожает объект внутри него, но не освобождает память.