Sé que esta pregunta ya se hizo varias veces, pero no pude encontrar una respuesta para este caso en particular.
Digamos que tengo una clase trivial que no posee ningún recurso y tiene un destructor vacío y un constructor predeterminado. Tiene un puñado de variables miembro con inicialización en clase; ninguno de ellos lo es const
.
Quiero reinicializar y objetar tal clase sin escribir el deInit
método a mano. ¿Es seguro hacerlo así?
void A::deInit()
{
new (this)A{};
}
No puedo ver ningún problema con él: el objeto siempre está en estado válido, this
todavía apunta a la misma dirección; pero es C ++, así que quiero estar seguro.
c++
placement-new
Amomum
fuente
fuente
*this = A{};
?*this = A{};
significa,this->operator=(A{});
es decir, crear un objeto temporal y asignarlo*this
, reemplazando los valores de todos los miembros de datos con los valores temporales. Como eso es lo que quieres y es (en mi opinión) más legible que una ubicación nueva, preferiría eso.Respuestas:
De manera similar a la legalidad de
delete this
, la colocación de nuevosthis
también está permitida hasta donde yo sé. Además, con respecto a sithis
, u otros punteros / referencias preexistentes pueden usarse después, hay algunas restricciones:Los dos primeros están satisfechos en este ejemplo, pero los dos últimos deberán tenerse en cuenta.
Con respecto al tercer punto, dado que la función no está calificada para const, debería ser bastante seguro asumir que el objeto original no es const. La falla está en el lado de la persona que llama si la constidad ha sido desechada. Con respecto al miembro const / reference, creo que puede verificarse afirmando que esto es asignable:
Por supuesto, dado que la asignabilidad es un requisito, en su lugar, simplemente puede usar
*this = {};
lo que esperaría para producir el mismo programa. Un caso de uso quizás más interesante podría ser reutilizar la memoria de*this
un objeto de otro tipo (lo que no cumpliría los requisitos para su usothis
, al menos sin reinterpretar + lavar).Similar a
delete this
, la ubicación nueva athis
difícilmente podría describirse como "segura".fuente
delete ptr
esnew T()
. El inverso denew(ptr)T{}
esptr->~T();
. stackoverflow.com/a/8918942/845092Las reglas que cubren esto están en [basic.life] / 5
y [basic.life] / 8
Como su objeto es trivial, no tiene que preocuparse por [basic.life] / 5 y siempre y cuando satisfaga los puntos de bala de [basic.life] / 8, entonces es seguro.
fuente