Вызвать деструктор вручную и повторно использовать память

Хотя я понимаю, что это, вероятно, не самая лучшая идея, я гипотетически спрашиваю:

Законно ли (то есть определенное поведение) вызывать объект
Деструктор вручную, а затем повторно использовать память для другого объекта?

Определения:

class A {
int a, b, c;
A() {}
~A() {}
}

A createObject() {
A object;
return object;
}

Код:

A* object = new A();
// Use object...
object->~A();
*object = createObject();

2

Решение

Вызывать деструктор явным образом — это законно, фактически это то, что вы делаете, когда используете размещение new. Инициализация объекта «на месте», когда память уже выделена, также допустима, но вы должны делать это иначе: вместо использования оператора присваивания вы можете использовать этот синтаксис:

object = new (object) A(); // Placement syntax

То, как вы это сделали (с помощью оператора присваивания), неверно, потому что вы вызываете функцию (то есть оператор присваивания) для объекта, деструктор которого завершен.

3

Другие решения

Вы не можете вызвать оператор присваивания для разрушенного объекта, как вы делаете. По крайней мере, в целом, хотя это может работать с некоторыми типами. Что вы можете сделать, это:

A* object = new A();
object->~A();
// Placement new.
// Constructs a new object in the memory pointed to by object pointer.
// Doesn't allocate memory.
new (object) A(createObject());

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

  1. Никогда не создавайте объект поверх уже существующего объекта, который не был разрушен.
  2. Никогда не звони delete на указатель после того, как вы вызвали деструктор для объекта, на который он указывает, пока вы не восстановите объект (того же типа) на его месте.
6

По вопросам рекламы [email protected]