Ich weiß, dass diese Frage bereits mehrmals gestellt wurde, aber ich konnte keine Antwort für diesen speziellen Fall finden.
Angenommen, ich habe eine triviale Klasse, die keine Ressourcen besitzt und einen leeren Destruktor und einen Standardkonstruktor hat. Es verfügt über eine Handvoll Mitgliedsvariablen mit klasseninterner Initialisierung. keiner von ihnen ist const
.
Ich möchte eine solche Klasse neu initialisieren und objektieren, ohne die deInit
Methode von Hand zu schreiben . Ist es sicher, das so zu machen?
void A::deInit()
{
new (this)A{};
}
Ich kann kein Problem damit erkennen - das Objekt befindet sich immer im gültigen Zustand und zeigt this
immer noch auf dieselbe Adresse. aber es ist C ++, also möchte ich sicher sein.
c++
placement-new
Amomum
quelle
quelle
*this = A{};
?*this = A{};
bedeutet,this->operator=(A{});
dh ein temporäres Objekt erstellen und zuweisen*this
, wobei die Werte aller Datenelemente durch die temporären Werte ersetzt werden. Da dies das ist, was Sie wollen und (meiner Meinung nach) besser lesbar sind als ein neues Praktikum, würde ich stattdessen damit anfangen.Antworten:
Ähnlich wie bei der Legalität von
delete this
ist meines Wissens auch eine neue Platzierungthis
zulässig. In Bezug darauf, obthis
oder andere bereits vorhandene Zeiger / Referenzen später verwendet werden können, gibt es einige Einschränkungen:Die ersten beiden sind in diesem Beispiel erfüllt, die letzten beiden müssen jedoch berücksichtigt werden.
In Bezug auf den dritten Punkt sollte angesichts der Tatsache, dass die Funktion nicht const-qualifiziert ist, ziemlich sicher angenommen werden, dass das ursprüngliche Objekt nicht const ist. Der Fehler liegt auf der Anruferseite, wenn die Konstanz weggeworfen wurde. In Bezug auf const / reference member denke ich, dass dies überprüft werden kann, indem behauptet wird, dass dies zuweisbar ist:
Da Zuweisbarkeit eine Voraussetzung ist, können Sie natürlich stattdessen einfach das verwenden, von
*this = {};
dem ich erwarten würde, dass es dasselbe Programm erzeugt. Ein vielleicht interessanterer Anwendungsfall könnte darin bestehen, den Speicher*this
für ein Objekt eines anderen Typs wiederzuverwenden (was die Anforderungen für die Verwendungthis
zumindest ohne Neuinterpretation + Waschen nicht erfüllen würde ).Ähnlich wie bei einer
delete this
neuen Platzierung kannthis
man kaum als "sicher" bezeichnen.quelle
delete ptr
istnew T()
. Die Umkehrung vonnew(ptr)T{}
istptr->~T();
. stackoverflow.com/a/8918942/845092Die Regeln, die dies abdecken, sind in [basic.life] / 5
und [basic.life] / 8
Da Ihr Objekt trivial ist, müssen Sie sich keine Sorgen um [basic.life] / 5 machen. Solange Sie die Aufzählungspunkte von [basic.life] / 8 erfüllen, ist es sicher.
quelle