Я знаю, что этот вопрос задавался уже несколько раз, но я не мог найти ответ для этого конкретного случая.
Допустим, у меня есть тривиальный класс, который не владеет никакими ресурсами и имеет пустой деструктор и конструктор по умолчанию. У него есть несколько переменных-членов с инициализацией в классе; ни один из них не является const
.
Я хочу повторно инициализировать и объект такого класса без написания deInit
метода от руки. Насколько это безопасно?
void A::deInit()
{
new (this)A{};
}
Я не вижу никаких проблем с ним - объект всегда находится в допустимом состоянии, this
все еще указывает на тот же адрес; но это C ++, поэтому я хочу быть уверен.
c++
placement-new
Amomum
источник
источник
*this = A{};
?*this = A{};
означает,this->operator=(A{});
то есть создать временный объект и назначить его*this
, заменив значения всех элементов данных значениями временного объекта . Так как это то, что вы хотите, и (на мой взгляд) более читабельно, чем новое место размещения, я бы пошел с этим вместо этого.Ответы:
Так же, как и законность
delete this
, размещение новых дляthis
также разрешено, насколько я знаю. Кроме того, в отношении тогоthis
, могут ли впоследствии использоваться другие уже существующие указатели / ссылки, существует несколько ограничений:Первые два удовлетворены в этом примере, но последние два должны быть приняты во внимание.
Что касается третьего пункта, учитывая, что функция не является константной, следует с уверенностью предположить, что исходный объект не является константным. Ошибка на стороне вызывающей стороны, если постоянство было отброшено. Что касается const / reference member, я думаю, что это можно проверить, утверждая, что это присваивается:
Конечно, поскольку присваиваемость является требованием, вместо этого вы могли бы просто использовать тот,
*this = {};
который я ожидал бы создать ту же программу. Возможно, более интересный вариант использования мог бы заключаться в повторном использовании памяти*this
для объекта другого типа (что не соответствовало бы требованиям для использованияthis
, по крайней мере, без повторной интерпретации + отмывания).Подобно тому
delete this
, что новое размещениеthis
вряд ли можно назвать «безопасным».источник
delete ptr
естьnew T()
. Инверсияnew(ptr)T{}
естьptr->~T();
. stackoverflow.com/a/8918942/845092Правила, которые покрывают это, находятся в [basic.life] / 5
и [basic.life] / 8
Поскольку ваш объект тривиален, вам не нужно беспокоиться о [basic.life] / 5, и пока вы удовлетворяете пунктам из [basic.life] / 8, тогда он безопасен.
источник