Für diese Frage ist der Ausgang CCCDCDD, und wenn ich das func() in der Hauptfunktion lösche, wird der Ausgang CCCDDD, ich verstehe die ersten 3 C, woher es kommt, aber ich verstehe nicht Bleib, bitte erkläre es, danke.Wie funktionieren der Konstruktor und der Destruktor?
Antwort
- C - a
- C konstruiert - b aufgebaut ist
- C - c aufgebaut ist
- D - c desctructed ist becouse Sie den Umfang
- C verlassen - ein Objekt Foo dynamisch ist zugewiesen und auf p gezeigt, aber da es dynamisch zugewiesen und nie gelöscht wird, wird es nie zerstört.
- D - b ist
- D destructed - a
destructed gibt es damit CCCDCDD wäre:
- C - Construct A
- C - Construct B
- C - Konstruieren C
- D - Zerstören C
- C - Konstrukt p (in func)
- D - Destruct B
- D - A Destruct
// memleak für p (in func)
Wenn der func();
Anruf enthalten ist, das nommenen Schritte sind:
Foo a; -> C
Foo b; -> C
Foo c; -> C
Left the scope of Foo c -> D
func(); call ->
new Foo; -> C
Finished func() call, left the scope of Foo b -> D
Left the scope of Foo a -> D
Beachten Sie, dass das Objekt Foo in func() erstellt wurde nie destrukturiert wird, das heißt, Sie einen Speicherverlust haben.
Der Umfang des Objekts a
ist der Umfang des äußeren Codeblocks der Funktion main. Es ist das erste Objekt, das erstellt wird, und das letzte Objekt, das gelöscht wird.
int main(){
Foo a;
// ...
return 0;
}
C C C D C D D
| |
a a
Dann wird in der for-Schleife, die nur eine Iteration hat es das Objekt erstellt wird b
die
for (int i=0; i<1; i++){
Foo b;
// ...
}
C C C D C D D
| | | |
a b b a
dann im Block Umfang der Anweisung, wenn
if (true){
Foo c;
}
wird erstellt und gelöscht das Objekt c
C C C D C D D
| | | | | |
a b c c b a
Danach wird die Funktion func
genannt wird
func();
Innerhalb der Funktion wird ein unbenanntes Objekt mit dem Operator neu und auf den durch den Zeiger p
erstellt.
Dieses Objekt wird nicht gelöscht, da der Operator delete für dieses Objekt nicht aufgerufen wird. Es gibt also ein Speicherleck.
Das ist alles.
- 1. Reihenfolge der Mitglieder Konstruktor und Destruktor Anrufe
- 2. Destruktor und Konstruktor in C
- 3. Excel VBA Objekt Konstruktor und Destruktor
- 4. C++ - Konstruktor, Konstruktor kopieren, Konstruktor verschieben, Destruktor
- 5. C++ Konstruktor/Destruktor
- 6. Warum heißt der Destruktor mehr als der Konstruktor?
- 7. Vektor Konstruktor/Destruktor ruft
- 8. Sperren freigegebener Ressourcen in Konstruktor und Destruktor
- 9. Ist es zulässig, den Destruktor/Konstruktor der Basisklasse explizit aufzurufen?
- 10. Erklären Reihenfolge der Konstruktor/Destruktor fordert in diesem C++ Code
- 11. Was ist der Unterschied zwischen "= Standard" Destruktor und leerer Destruktor?
- 12. Kann der Destruktor den Destruktor eines bestimmten Feldes NICHT aufrufen?
- 13. Konstruktor \ Destruktor oder Verständnis von OOP
- 14. Ändern der Destruktor-Reihenfolge
- 15. Pimpl mit Smart ptr - Warum Konstruktor/Destruktor
- 16. Unterklasse von QObject, qRegisterMetaType und der Konstruktor der privaten Kopie
- 17. Erwarteter Konstruktor, Destruktor oder Typkonvertierung vor '*' Token
- 18. Warum verursacht der Destruktor einen Segmentierungsfehler?
- 19. Konstruktor/Destruktor mit einer Klasse und einer Struktur
- 20. Verknüpfte Liste und der Konstruktor
- 21. Wie wird der C++ - Konstruktor für den Move-Konstruktor von flüchtigen und virtuellen Membern beeinflusst?
- 22. Wird der Destruktor beim Delegieren eines delegierenden Konstruktors aufgerufen?
- 23. Wie funktioniert der const-Konstruktor?
- 24. Konstruktor/Destruktor, definiert durch Merkmal, wird nicht aufgerufen
- 25. C2694 auf Destruktor, wenn der Destruktor der Basisklasse 'Members hat nicht-leere noexcept-Spezifizierer und ein Körper
- 26. Destruktor der Vorlage Klasse mit Zeiger
- 27. Warum ruft der Destruktor der Basisklasse das abgeleitete Objekt auf, wenn der Destruktor der abgeleiteten Klasse nicht virtuell ist?
- 28. Fehler: erwartete Konstruktor-, Destruktor- oder Typkonvertierung vor '*' Token |
- 29. Warum scheint mein Destruktor häufiger aufgerufen zu werden als der Konstruktor?
- 30. Warum wird der Destruktor beim Initialisieren und Ändern der Größe eines Objektvektors aufgerufen?
'für (int i = 0; i <1; i ++)' führt im Wesentlichen seinen Block einmal aus, so auch 'if (true)'. Wenn Sie einen Bereich definieren möchten, können Sie einfach ein Paar Klammern ('{}') verwenden. Sie müssen sie nicht im Kontext einer Flow-Control-Anweisung verwenden. Sie könnten einfach 'int main() {Foo a; {Foo b; {Foo c; } func(); } zurückgeben 0; } ' –
Das Durchlaufen mit einem Debugger könnte helfen ... – Borgleader
' p = NULL; 'zerstört das Objekt nicht wirklich. Das "neue Foo" -Objekt ist durchgesickert. Diese Zeile sollte 'delete p;' lauten. – cdhowie