Ich habe ein Tetris-Spiel erstellt, in dem du nach einem Spiel neu starten kannst. Ich habe das schnell und dreckig mit einem Goto implementiert (siehe Code). Die Klasse Game
beruht auf Destruktoren, werden diese mit diesen Goto's aufgerufen? Wie schlimm ist das, ist es akzeptabel, oder was soll ich stattdessen tun?
Um die Frage nach Destruktoren zu beantworten, die sonst niemand zu behandeln scheint. Nach 6.6 / 2 werden die Destruktoren für Sie aufgerufen. Quote:
Beim Verlassen eines Bereichs (jedoch vollendet), Destruktoren (12.4) sind rief nach allen konstruierten Objekten mit automatischer Speicherdauer (3.7.2) (benannte Objekte oder Provisorien) die in diesem Bereich erklärt werden, die umgekehrte Reihenfolge ihrer Erklärung. Aus einer Schleife übertragen, aus einem Block oder zurück an einem initialisierte Variable mit automatischem Speicherdauer umfasst die Zerstörung von Variablen mit automatische Speicherdauer in Umfang an dem Punkt übertragen von aber nicht an dem Punkt übertragen zu.
Allerdings schlage ich in diesem Fall überhaupt nicht goto
vor. Es ist nicht klar (für mich), was passiert. Sie sollten nur eine while-Schleife verwenden und stattdessen die Bedingungen bearbeiten.
Selbst etwas so Einfaches wie dieses sollte klarer sein (obwohl es wahrscheinlich einen Weg gibt, es ohne den inneren Bruch neu zu schreiben). Es ist vollkommen klar, dass die Einheimischen in einer solchen Zeitschleife wie folgt gereinigt werden:
%Vor% Sie können dies leicht vermeiden, indem Sie die Mehrheit dieser Funktion in eine while
-Schleife setzen und ein Flag setzen, um daraus auszubrechen.
In C war die einzige echte "akzeptable" Verwendung von goto
das Springen zu häufigem Bereinigungscode im Falle von Fehlern. In C ++ können Sie dies sogar mit Ausnahmen vermeiden. Also wirklich, es gibt keine Entschuldigung!
Anstelle von goto können Sie alles von Ihrem newgame -Tag bis zum Ende der while-Schleife in einer Funktion einfügen. Der Rückgabewert dieser Funktion würde Ihnen sagen, ob Sie erneut laufen müssen. Also wäre es etwa so:
%Vor%Sie müssten runGame () Parameter von Ihrer Hauptfunktion, die Sie in Ihrem Spielcode verwenden, weitergeben und eine 1 zurückgeben, wobei der Code das goto und a verwendet Null, wenn es das letzte Spiel ist.
Brechen Sie die signifikanten Blöcke in Funktionen auf und rufen Sie dann nicht goto
auf, sondern rufen Sie stattdessen eine Funktion auf.
Gotos sind selten gut zu benutzen. Die Ausnahme scheint für die Bereinigung zu sein, wo Sie schnell aus vielen verschachtelten Schleifen ausbrechen müssen, etwas Speicher freigeben und beenden müssen. Dies kann hier leicht durch eine while-Schleife ersetzt werden. Wenn es so bleibt wie es ist, wird es nur das Debugging und die Wartung erschweren.
Es gibt einige gute Zeiten, um goto
zu benutzen (zB: Implementieren eines Zustandsautomaten), aber ich bin mir nicht sicher, ob das wirklich einer von ihnen ist.
Wenn ich es wäre, würde ich den "Spiel" -Code in eine Subroutine setzen, ihn beenden, wenn er fertig ist, und dann die höhere Routine wählen lassen, ein neues Spiel oder etwas zu starten.