Je sais que cette question a déjà été posée plusieurs fois mais je n'ai pas trouvé de réponse pour ce cas particulier.
Disons que j'ai une classe triviale qui ne possède aucune ressource et qui a un destructeur vide et un constructeur par défaut. Il a une poignée de variables membres avec initialisation en classe; aucun d'entre eux ne l'est const
.
Je veux réinitialiser et objecter une telle classe sans écrire de deInit
méthode à la main. Est-il sûr de le faire comme ça?
void A::deInit()
{
new (this)A{};
}
Je ne vois aucun problème avec lui - l'objet est toujours dans un état valide, this
pointe toujours vers la même adresse; mais c'est C ++ donc je veux être sûr.
c++
placement-new
Amomum
la source
la source
*this = A{};
?*this = A{};
signifie,this->operator=(A{});
c'est-à-dire créer un objet temporaire et l'affecter à*this
, en remplaçant les valeurs de tous les membres de données par les valeurs du temporaire. Puisque c'est ce que vous voulez et est (à mon avis) plus lisible qu'un nouveau placement, j'irais avec cela à la place.Réponses:
De la même manière que pour la légalité
delete this
, le placement nouveauthis
est également autorisé à ma connaissance. En outre, concernant l'this
utilisation éventuelle d'autres pointeurs / références préexistants, il existe quelques restrictions:Les deux premiers sont satisfaits dans cet exemple, mais les deux derniers devront être pris en considération.
En ce qui concerne le troisième point, étant donné que la fonction n'est pas qualifiée const, il devrait être assez sûr de supposer que l'objet d'origine est non const. La faute est du côté de l'appelant si la constance a été rejetée. En ce qui concerne const / reference member, je pense que cela peut être vérifié en affirmant que c'est assignable:
Bien sûr, comme l'attribution est une exigence, vous pouvez simplement utiliser
*this = {};
ce à quoi je m'attendrais pour produire le même programme. Un cas d'utilisation peut-être plus intéressant pourrait être de réutiliser la mémoire d'*this
un objet d'un autre type (ce qui ne répondrait pas aux exigences d'utilisationthis
, au moins sans réinterprétation + blanchiment).De même
delete this
, un placement nouveauthis
pourrait difficilement être décrit comme «sûr».la source
delete ptr
estnew T()
. L'inverse denew(ptr)T{}
estptr->~T();
. stackoverflow.com/a/8918942/845092Les règles qui couvrent cela se trouvent dans [basic.life] / 5
et [basic.life] / 8
Étant donné que votre objet est trivial, vous n'avez pas à vous soucier de [basic.life] / 5 et tant que vous satisfaites les puces de [basic.life] / 8, alors il est sûr.
la source