Wenn ich eine Schleife habe und innerhalb dieser Schleife eine neue Stapelvariable erstelle (ohne sie auf dem Heap zuzuweisen und die Variable, die sie im Schleifenkörper deklariert hält), wird der Destruktor dieses Objekts garantiert aufgerufen, bevor die nächste Iteration beginnt oder möglicherweise Schleife Abwickeln durch den Compiler etwas daran ändern?
c++
destructor
user1282931
quelle
quelle
Antworten:
Von
n4800
:§6.3.3 Block - Scope :
§10.3.6 Zerstörer :
§4.1.1 Abstrakte Maschine :
[Hervorhebung von mir]
Also ja. Ihre Variable verlässt am Ende der Schleife (die ein Block ist) den Gültigkeitsbereich und daher wird ihr Destruktor aufgerufen , soweit jeder, der das Verhalten des Programms beobachtet, dies beurteilen kann .
quelle
call
. Oder wenn sie effektiv (als ob-Regel) nichts tun, wird möglicherweise keine Baugruppe für solche Destruktoren generiert.Ja. Es ist einfacher zu visualisieren, wenn Sie die "Blöcke" betrachten, in denen Sie eine Variable deklarieren, dh zwischen welchen Klammern. Die Schleife ist ein Block für sich, und wenn sie vor der nächsten Iteration die schließende Klammer erreicht, werden alle Destruktoren der in der Schleife deklarierten automatischen Speichervariablen aufgerufen.
Als Faustregel sollten Sie nicht darüber nachdenken, was der Compiler optimieren wird, da er weiterhin das Verhalten Ihres Programms gewährleisten muss, unabhängig davon, was es zur Optimierung tut. In diesem Fall ändert das Abrollen der Schleife nichts in diesem Sinne, wenn dies geschieht.
quelle
[class.copy.elision]
for(...) X x{};
und dasx
Objekt wird in jeder Iteration konstruiert + zerstört. Live-Demo . Ein relevanter Standardabschnitt ist stmt.iter / 2 .[stmt.iter]
es rein äquivalent (Hervorhebung von mir): "Wenn die Unteranweisung in einer Iterationsanweisung eine einzelne Anweisung und keine zusammengesetzte Anweisung ist, ist es so, als ob sie als zusammengesetzte Anweisung umgeschrieben wurde die ursprüngliche Aussage. ". Im Wesentlichen bedeutet mit oder ohne Klammern für eine einzelne Anweisung genau dasselbe, und die Klammern sind implizit. Ich habe es aus Gründen der Klarheit weggelassen.Der Destruktor wird für jede Iteration aufgerufen. In einigen Fällen ist es daher schneller, eine Variable außerhalb der Schleife als in der Schleife zu deklarieren . Angenommen, der folgende Fall:
Der Destruktor wird nicht aufgerufen, wenn die Verwendung der Schleife ausgeführt wird. Es überschreibt nur
temp
.Wenn Sie jedoch
std::string temp = arr[i]
den Konstruktor verwenden, wird der Destruktor für jede Iteration aufgerufen. Ich denke, dies fügt ein bisschen Laufzeit hinzu, falls Sie eine Schleife haben, die sehr oft ausgeführt wird.quelle
Der Destruktor wird vor der nächsten Iteration aufgerufen
quelle
Natürlich wird dtor am Ende der Iteration aufgerufen, und das Abrollen der Schleife sollte dieses Verhalten nicht ändern, wie jede andere Optimierung (eine Optimierung sollte das Programmverhalten nicht ändern), außer einer Art RVO und dergleichen, die einige semantisch falsche Objekterstellungen eliminieren kann .
quelle