Es ist nicht unbedingt eine schlechte Idee, aber normalerweise, ja.
Erstens sind es globale Daten und Globals sind normalerweise eine schlechte Sache. Je globaler Sie sind, desto schwieriger wird es, über Ihr Programm nachzudenken.
Zweitens garantiert C ++ keine Initialisierungsreihenfolge von statischen Objekten, die in verschiedenen Übersetzungseinheiten (.cpp-Dateien) definiert sind. Wenn sie also voneinander abhängen, können Sie Probleme haben.
Ja, das ist schlecht. Da Sie keine Möglichkeit haben, Ausnahmen abzufangen und damit umzugehen, wird der Standard-Handler verwendet. In C ++ bedeutet das den Aufruf von terminate ...
Beispiel: Inhalt a.cpp
Ausgabe von: g++ a.cpp && ./a.out
Sie können versuchen, ein try ... catch
in Ihrem main hinzuzufügen, das wird nicht helfen.
Bearbeiten: Jalfs Punkte sind auch gültig. Höre auf seinen Rat.
Wie Sie betonen, ist es erlaubt. In der letzten Firma, in der ich gearbeitet habe, haben wir in einer solchen Situation die Politik gemacht, main () einen entsprechenden Kommentar hinzuzufügen, um anzugeben, für welche Variablen dies galt. Wenn Sie eine schlechte Situation haben, versuchen Sie, das Beste daraus zu machen.
Die Verwendung von globalen / statischen Objekten mit nicht-trivialen Konstruktoren und Destruktoren ist schrecklich . Ich habe genug riesige Software-Projekte gesehen, die sich in einer Katastrophe befanden, weil unkontrollierte globale / statische Objekte und Einzeltöne verwendet wurden.
Das Problem ist nicht die Tatsache, dass es der Code ist, der außerhalb von main
ausgeführt wird. Es ist, dass diese Objekte in einer unkontrollierbaren Reihenfolge konstruiert und zerstört werden.
Außerdem glaube ich, dass es generell eine schlechte Praxis ist, globale Variablen (auch gewöhnliche Variablen) zu verwenden, mit einigen Ausnahmen. Jedes Stück Code sollte in einem gut definierten Kontext ausgeführt werden, und alle Variablen sollten dazu gehören.
Es ist überhaupt keine schlechte Form und es ist nicht verwirrend. Die statische Initialisierung ist eine bewusste Eigenschaft der Sprache. Verwenden Sie es, wenn Sie müssen. Gleiches gilt für Globals. Verwenden Sie sie bei Bedarf. Wie jedes Feature ist es ein starker Programmierer, zu wissen, wann es angemessen ist und seine Grenzen zu kennen.
Schlechte Form restrukturiert ein ansonsten perfektes Programm, um Globals oder statische Initialisierung zu vermeiden.
Zusätzlich zu der fraglichen Form - Es wird nicht auf einigen Plattformen portierbar sein.
Die Konstruktoren von global deklarierten Klassen werden aufgerufen, bevor main eingegeben wird. Während dies für einen neuen Leser des Codes verwirrend sein kann, weil es so selten geschieht, ist es notwendigerweise eine schlechte Idee?
Ja, das ist schlecht. Da Sie keine Möglichkeit haben, Ausnahmen abzufangen und damit umzugehen, wird der Standard-Handler verwendet. In C ++ bedeutet das den Aufruf von terminate ...
Beispiel: Inhalt %code%
%Vor%Ausgabe von: %code%
%Vor%Sie können versuchen, ein %code% in Ihrem main hinzuzufügen, das wird nicht helfen.
Bearbeiten: Jalfs Punkte sind auch gültig. Höre auf seinen Rat.
Wie Sie betonen, ist es erlaubt. In der letzten Firma, in der ich gearbeitet habe, haben wir in einer solchen Situation die Politik gemacht, main () einen entsprechenden Kommentar hinzuzufügen, um anzugeben, für welche Variablen dies galt. Wenn Sie eine schlechte Situation haben, versuchen Sie, das Beste daraus zu machen.
Es ist überhaupt keine schlechte Form und es ist nicht verwirrend. Die statische Initialisierung ist eine bewusste Eigenschaft der Sprache. Verwenden Sie es, wenn Sie müssen. Gleiches gilt für Globals. Verwenden Sie sie bei Bedarf. Wie jedes Feature ist es ein starker Programmierer, zu wissen, wann es angemessen ist und seine Grenzen zu kennen.
Schlechte Form restrukturiert ein ansonsten perfektes Programm, um Globals oder statische Initialisierung zu vermeiden.
Die Verwendung von globalen / statischen Objekten mit nicht-trivialen Konstruktoren und Destruktoren ist schrecklich . Ich habe genug riesige Software-Projekte gesehen, die sich in einer Katastrophe befanden, weil unkontrollierte globale / statische Objekte und Einzeltöne verwendet wurden.
Das Problem ist nicht die Tatsache, dass es der Code ist, der außerhalb von %code% ausgeführt wird. Es ist, dass diese Objekte in einer unkontrollierbaren Reihenfolge konstruiert und zerstört werden.
Außerdem glaube ich, dass es generell eine schlechte Praxis ist, globale Variablen (auch gewöhnliche Variablen) zu verwenden, mit einigen Ausnahmen. Jedes Stück Code sollte in einem gut definierten Kontext ausgeführt werden, und alle Variablen sollten dazu gehören.
Ich werde so weit gehen müssen zu sagen, dass es eine schlechte Form für Nicht-PODs ist, besonders wenn Sie in einem Team arbeiten, hauptsächlich aufgrund von Problemen bei der Initialisierung, die leicht daraus entstehen können.
%Vor%Menschen schreiben im Allgemeinen keinen Code wie oben, sondern überlegen, ob der Erfolg mit dem Rückgabewert einer anderen Funktion initialisiert wurde. Jeder, der versucht hat, cout oder cerr oder ein anderes globales Objekt in dieser Funktion zu verwenden, hat das gleiche undefinierte Verhalten ausgelöst.
Berücksichtigen Sie bei benutzerdefinierten Typen mit Konstruktoren und Destruktoren die alternative Methode, bei der der Zugriff initialisiert wird:
%Vor%Leider hat dies auch Probleme mit der Thread-Sicherheit, so dass ein Sperrmechanismus für den Aufbau von 'f' erforderlich ist, wenn Sie gleichzeitig auf safe_static zugreifen.
Das heißt, ich denke, man sollte versuchen, die Dinge einfach zu halten. Leider ist es bei benutzerdefinierten Objekten, die im Dateibereich definiert sind, viel zu einfach, in ein undefiniertes Verhalten zu geraten. Der kleine zusätzliche Aufwand, um etwas wie safe_static oben zu schreiben, kann viele Kopfschmerzen verhindern.
Ausnahmen sind ein anderer Punkt. Wenn Ihre statischen Objekte den Konstruktor verlassen, haben Sie keine Möglichkeit, die Ausnahme abzufangen. Wenn Sie möchten, dass Ihre Anwendung wirklich robust ist und sogar Startfehler behandelt, müssen Sie Ihren Code sorgfältig strukturieren (z. B. try / catch-Blöcke in den Konstruktoren für die Objekte, die Sie im Dateibereich erstellen, sodass die Ausnahme nicht ausgelöst wird außerhalb des ctor und vermeiden auch Initialisierungslisten, die werfen).
Wenn Sie in einem Team arbeiten, denken Sie vielleicht an sich selbst: "Oh, ich greife nicht auf irgendwelche anderen Globals in meiner Klasse zu, ich könnte es genauso gut zu einem einfachen globalen System mit interner Verknüpfung im Dateibereich machen." Das mag dann stimmen, aber bevor Sie es wissen, fügt Ihr Kollege eine weitere globale Variable hinzu und versucht, darauf vom Konstruktor Ihrer Klasse zuzugreifen. Plötzlich haben Sie ein undefiniertes Verhalten, das möglicherweise nicht einmal ein Problem auf der Hauptplattform darstellt, auf die Sie nur abzielen, wenn Ihr Code abstürzt und andere seltsame Dinge tut, wenn Sie versuchen, Ihren Code anderweitig zu portieren.
Es ist wirklich nicht die potenziellen Kopfschmerzen IMO wert, und es ist ein Problem, das viel einfacher zu vermeiden als zu beheben ist.
Es ist nicht unbedingt eine schlechte Idee, aber normalerweise, ja.
Erstens sind es globale Daten und Globals sind normalerweise eine schlechte Sache. Je globaler Sie sind, desto schwieriger wird es, über Ihr Programm nachzudenken.
Zweitens garantiert C ++ keine Initialisierungsreihenfolge von statischen Objekten, die in verschiedenen Übersetzungseinheiten (.cpp-Dateien) definiert sind. Wenn sie also voneinander abhängen, können Sie Probleme haben.
Tags und Links c++ constructor