2010-07-05 5 views
37

Betrachten Sie den folgenden Code ein:Gehe aus einem Block heraus: Werden Destruktoren aufgerufen?

void foo() 
{ 
    { 
     CSomeClass bar; 

     // Some code here... 

     goto label; 

     // and here... 
    } 

label: 
    // and here... 
} 

Wird der destructor der Bar genannt werden?

+0

Warum müssen Sie das wissen? 'goto' macht im generierten Code Sinn, aber dort können und sollten Sie Objekte mit Destruktoren sowieso vermeiden. – MSalters

+13

@MSalters: Das macht überhaupt keinen Sinn, warum sollten Sie Objekte mit Destruktoren vermeiden? –

+1

@Viktor: Lassen Sie mich den zweiten Teil des Satzes erweitern: _In generated code_, können und sollten Sie Objekte mit Destruktoren sowieso vermeiden. Die kanonische Verwendung von 'goto' ist im generierten FSM-Code. Hier finden Sprünge rückwärts und vorwärts statt, ohne Rücksicht auf Zustandscodezustände, die gerade in der Mitte liegen. FSM-Zustände sind einfach nicht linear, aber C++ Code muss sein. – MSalters

Antwort

52

der C++ Standard sagt:

beim Ausgang aus einem Rahmen (jedoch versierte), Destruktoren (12.4) ist für alle konstruierten Objekte mit automatischer Speicherdauer genannt (3.7.2) (benannt O Objekte oder Provisorien) , die in diesem Bereich deklariert sind, in die umgekehrte Reihenfolge ihrer Deklaration.

Also die Antwort ist "Ja".

+0

Danke. Das habe ich gebraucht. –

9

1) Ja. 2) Tun Sie das nicht.

Ausarbeitung: konzeptionell unterscheidet sich nicht davon, eine Schleife über eine break zu verlassen. goto wird jedoch dringend davon abgeraten. Es ist fast nie notwendig, goto zu verwenden, und jede Verwendung sollte genau untersucht werden, um herauszufinden, was vor sich geht.

+0

Perfekte Antwort. – Mizipzor

+1

2) Sie tun dies, wenn Sie Schleifen tatsächlich entkommen. –

+14

Eigentlich macht in vielen Fällen Sinn. –

21

Ja, sie werden angerufen werden.

Update: (.. Es ist in Ordnung, dies zu tun, gotos ist nicht schlechter als Dummy-Ausnahmen zu werfen oder bools/ifs mit aus der Dinge zu bekommen Eine einfache gehe in einer Funktion Sie es nicht Spaghetti-Code machen)

+7

+1, um den egoistischen Studenten zu negieren, der das Bedürfnis verspürte, zu downvoten, weil sie persönlich denken, dass Goten böse sind. Gotos haben gültige Nutzungen, Leute, ungeachtet dessen, was deine Professoren dir gesagt haben. – KevenK

+2

"Es ist in Ordnung, dies zu tun, GOTOS ist nicht schlimmer als Dummy-Ausnahmen zu werfen oder bools/ifs zu benutzen." Eine Dummy-Ausnahme zu werfen ist eine schreckliche Art, dies zu tun (das Auslösen von Ausnahmen ist in der Regel extrem teuer) und wenn es dazwischen ist Das und Gotos, ich würde definitiv Gotos bevorzugen. Allerdings ist das Schreiben von Funktionen für diese Fälle sicherlich der beste Weg zu gehen. – stinky472

+1

@KevinK - Gotos kann in der Theorie gültige Anwendungen haben, aber sie sind in der Praxis extrem selten. Ich würde argumentieren, dass, wenn es so aussieht, als ob man ein Goto verwenden muss, die Situation zumindest näher untersucht werden muss. Und für beginnende Entwickler würde ich vorschlagen, sie zu meiden, ist eine gute Disziplin, um zu lernen. – jwismar

4

Ja, wie alle anderen auch sagen. C++ spezifiziert/mandatiert dies.

Aber nur, dass für Vollständigkeit hinzuzufügen: Wenn Ihr goto die computed- goto Erweiterung in einigen Compilern gefunden verwendet - gcc, Klirren, möglicherweise andere, aber nicht einschließlich MSVC zuletzt wusste ich - ob die Der Destruktor des Objekts, der aufgerufen wird, ist ziemlich verschwommen. Wenn ein goto an einen einzigen Ort geht, ist es sehr klar, welche Destruktoren vor der Kontrollflussübertragung aufgerufen werden müssen. Aber mit einer berechneten goto, verschiedene Destruktoren müssen möglicherweise dynamisch aufgerufen werden, um die "erwartete" Semantik zu geben. Ich bin nicht sicher, welche Compiler, die diese Erweiterung implementieren, in diesen Fällen tun. Meine Erinnerung daran ist, dass der Clam warnt, wenn ein Computer einen Bereich mit einem Objekt mit einem Nicht-Trial-Destruktor belässt und behauptet, dass der Destruktor nicht aufgerufen wird. In einigen Fällen ist das in Ordnung, in anderen nicht. Ich weiß nicht, was andere Compiler tun. Seien Sie sich des Problems nur bewusst, wenn Sie berechnete goto s zusammen mit Objekten mit nicht-trivialen Destruktoren verwenden möchten.

+0

Danke. Ich benutze nur berechnete Gotos von C und in sehr seltenen Situationen. –