Hallo C++ Experten, struct X { X(int i) throw(std::runtime_error) : i(i) { if(i==0) throw std::runtime_error("blabla"); } int i; }x(0); int main() { } Ich sehe keine Möglichkeit hier die Exception abzufangen, oder? Ausser in Konstruktor selbst natürlich. Verbietet Standard sowas überhaupt? Exception ausm Konstruktor schmeissen ist glaube ich erlaubt. Grüsse und schönen Sonntag Euch.
Der Standard verbietet das nicht. Da die Ausnahme in der Initialisierungsphase auftritt, in der noch kein catch im eigenen Code greifen kann, wird sie vom Startup-Code der RTL oder vom Betriebssystem behandelt - ein Absturz bevor noch main gerufen ist wird die Folge sein.
> Ich sehe keine Möglichkeit hier die Exception abzufangen, oder? > Ausser in Konstruktor selbst natürlich. Du kannst höchstens davon ableiten und im Konstruktor der abgeleiteten Klasse die Exception fangen. > wird sie vom Startup-Code der RTL Was hat das Fernsehen damit zu tun?
Rolf Magnus wrote: > Du kannst höchstens davon ableiten und im Konstruktor der abgeleiteten > Klasse die Exception fangen. Das wird nicht funktionieren, denn dazu müßte man den vom Compiler implizit generierten Aufruf des Konstruktors in einen try-Block einschließen. Das läßt jedoch die C++ - Syntax nicht zu. Bei Variablen auf Modullevel ist da nichts zu machen - außer den Startup-Code zu modifizieren, oder selbst zu schreiben. Wieviel Sinn das macht, kann sich jeder selbst überlegen... > >> wird sie vom Startup-Code der RTL > > Was hat das Fernsehen damit zu tun? RTL = RunTimeLibrary
> Das wird nicht funktionieren, denn dazu müßte man den vom Compiler > implizit generierten Aufruf des Konstruktors in einen try-Block > einschließen. Genau. > Das läßt jedoch die C++ - Syntax nicht zu. Das ist Unsinn. Man kann die Exception fangen, aber sie wird automatisch wieder geworfen. Das kann man meines Wissens nicht verhindern. Um mal das Originalbeispiel aufzugreifen:
1 | #include <iostream> |
2 | #include <stdexcept> |
3 | |
4 | struct X { |
5 | X(int i) throw(std::runtime_error) : i(i) { |
6 | if(i==0) |
7 | throw std::runtime_error("blabla"); |
8 | }
|
9 | int i; |
10 | };
|
11 | |
12 | struct Y : public X |
13 | {
|
14 | Y(int i) |
15 | try
|
16 | : X(i) |
17 | {
|
18 | }
|
19 | catch (std::exception& ex) |
20 | {
|
21 | std::cout << "Ausnahme gefangen: " << ex.what() << '\n'; |
22 | }
|
23 | };
|
24 | |
25 | Y y(0); |
26 | |
27 | int main() { |
28 | }
|
>>> wird sie vom Startup-Code der RTL >> >> Was hat das Fernsehen damit zu tun? > >RTL = RunTimeLibrary Ach die CRT ;-)
> Das kann man meines Wissens nicht verhindern.
Also nützen die ganzen Komplikationen in dem Fall nichts. Es macht ja
schließlich keinen Sinn, ein Objekt als konstruiert zurückzugeben, bei
dem ein Konstruktor einer Basisklasse gescheitert ist.
Exceptions in Konstruktoren sind ein heikles Thema - wenn man nicht
aufpaßt, produziert man damit ein Speicherleck nach dem anderen.
> Also nützen die ganzen Komplikationen in dem Fall nichts. Naja, du kannst die Exception auswerten und darauf reagieren. Du kannst sie aber nicht unter den Teppich kehren. > Es macht ja schließlich keinen Sinn, ein Objekt als konstruiert > zurückzugeben, bei dem ein Konstruktor einer Basisklasse gescheitert > ist. Das ist vermutlich auch der Grund, warum die Exception dann in jedem Fall weitergeworfen wird. > Exceptions in Konstruktoren sind ein heikles Thema - wenn man nicht > aufpaßt, produziert man damit ein Speicherleck nach dem anderen. Allerdings sind sie auch die einzige Möglichkeit (abgesehen von zusätzlichen Membervariablen, die man später prüfen kann), um aus dem Konstruktor heraus einen Fehler zu melden.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.