Wenn ein Konstruktor eine Ausnahme auslöst, macht es dann Sinn, ein globales Objekt dieser Klasse zu haben?

8

Ich frage diese Frage nach allgemeinen Kodierungsrichtlinien:

%Vor%

Wenn obj eine Ausnahme im obigen Code auslöst, wird der Code eventuell beendet, bevor main() aufgerufen wird. Also meine Frage ist, welche Richtlinie sollte ich für ein solches Szenario nehmen? Ist es in Ordnung, globale Objekte für solche Klassen zu deklarieren oder nicht? Sollte ich mich immer davon abhalten, oder ist es eine gute Tendenz, den Fehler am Anfang selbst zu verstehen?

    
iammilind 08.08.2011, 15:04
quelle

6 Antworten

4

Wenn Sie NEED eine globale Instanz eines Objekts verwenden, dessen Konstruktor auslösen kann, können Sie stattdessen die Variable statisch machen:

%Vor%

Dies würde das Problem durch eine vorzeitige Ausnahme verringern.

BEARBEITEN: Natürlich ist die Lösung in diesem Fall 90% des Weges zu einem Singleton. Warum verwandelst du es nicht einfach in eins, indem du f() in A verschiebst?

    
J T 08.08.2011 15:21
quelle
1

Nein, Sie sollten solche Objekte nicht global deklarieren - jede Ausnahme wird nicht behandelt und ist sehr schwer zu diagnostizieren. Das Programm wird einfach abstürzen, was bedeutet, dass es eine sehr schlechte (unter Null liegende) Benutzererfahrung hat und ziemlich schwer zu warten ist.

    
sharptooth 08.08.2011 15:08
quelle
0

Wie @Kerrek SB in den Kommentaren erwähnt hat, hängt die Antwort davon ab, aus welchen Gründen deine Klasse werfen kann. Wenn Sie versuchen, eine Systemressource zu erwerben, die möglicherweise nicht verfügbar ist, sollten Sie kein globales Objekt deklarieren. Ihr Programm stürzt ab, sobald der Benutzer versucht, es auszuführen. Das sieht natürlich nicht besonders gut aus. Wenn es eine std::bad_alloc oder eine solche Ausnahme auslösen kann, die unter normalen Umständen unwahrscheinlich ist (vorausgesetzt, Sie versuchen nicht, ein paar GB Arbeitsspeicher zuzuweisen), könnten Sie eine globale Instanz erstellen. das würde ich aber immer noch nicht machen.

Stattdessen könnten Sie einen globalen Zeiger auf das Objekt deklarieren, das Objekt direkt am Anfang von main instanziieren (bevor irgendwelche Threads erzeugt wurden usw.) und den Zeiger auf diese Instanz richten und dann über den Zeiger darauf zugreifen . Dies gibt Ihrem Programm die Möglichkeit, Ausnahmen zu behandeln und den Benutzer zu veranlassen, eine Art von Abhilfemaßnahmen zu ergreifen (z. B. die Schaltfläche Wiederholen, um die Ressource erneut zu erfassen).

    
Praetorian 08.08.2011 15:21
quelle
0

Das Deklarieren eines globalen Objekts ist in Ordnung, aber das Design Ihrer Klasse ist unbedeutend, es fehlen Details, die mit den praktischen Bedürfnissen und der Verwendung kompatibel sind.

    
Sutton 08.08.2011 15:26
quelle
0

Eine Lösung, die niemand zu erwähnen scheint, ist die Verwendung einer Funktion try Block. Grundsätzlich, wenn die Situation ohne das Konstruierte ist Objekt, der Rest Ihres Programms wird nicht funktionieren oder in der Lage sein, etwas zu tun nützlich, dann ist das einzige wirkliche Problem, dass Ihr Benutzer eine Art bekommen wird der unverständlichen Fehlermeldung, wenn der Konstruktor mit einem endet Ausnahme. So wickeln Sie den Konstruktor in eine Funktion try Block und generiere eine verständliche Nachricht, gefolgt von einer Fehlerrückgabe:

%Vor%

Diese Lösung ist jedoch nur dann sinnvoll, wenn alle Instanzen von das Objekt wird statisch deklariert, oder wenn Sie einen einzelnen isolieren können Konstruktor für die statischen Instanzen; für die nicht-statischen Instanzen, es ist wahrscheinlich besser, die Ausnahme zu propagieren.

    
James Kanze 08.08.2011 15:50
quelle
0

Wie @J T gesagt haben, können Sie so schreiben:

%Vor%

Ein solches Szenario ist ein ziemliches Problem. Bitte lesen Sie ERR58-CPP. Behandeln Sie alle Ausnahmen, die ausgelöst werden, bevor main () mit der Ausführung beginnt , um weitere Details zu erhalten.

    
selfboot 19.11.2017 07:31
quelle