Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

11

11.11.2008, 19:24

Zitat von »"Nox"«

Besser ne Zombieklasse als nen Speicherwrack :lol:.
Naja, man kann durch Zombies auch leicht Memory Leaks haben. Oder Speicherzugriffsfehler, wenn im Destruktor wieder versucht wird, Speicher freizugeben, der nie angefordert wurde.

Zitat von »"Nox"«

Sprich es sollte eine Ausnahme sein und nicht als Rückgabewert missbraucht werden. Aber das ist nur meine eigene Meinung und keinesfalls allgemeingültig.

Zitat von »"Nox"«

Mal ne allgemeine Antwort: Dazu wird dir wohl jeder ne andere Antwort geben bzw. gibt es da "zwei Lager". Die einen sagen, dass man (salopp ausgedrückt) Exceptions als Returnanweisungen nutzen darf und sollte. Die anderen behaupten, dass Exceptions echt nur für Ausnahmen sind.
Ich würde sagen, die Meinung über Exceptions ist ziemlich allgemeingültig. Exception bedeutet ja bereits übersetzt Ausnahme. Eigentlich sollten Exceptions auch nur in Ausnahmefällen eingesetzt werden. Dieser Begriff erlaubt natürlich einigen Spielraum, aber als Returnwert würde ich Exceptions sicher nicht durchgehen lassen - und ich glaube, das sehen die meisten so. ;)

Man kann auch Returnwerte benutzen, um einen Fehler anzuzeigen - es kommt halt auf den Kontext an. Exceptions sollten jedoch im Mass eingesetzt werden und dürften in der Praxis in den meisten Fällen nicht auftreten. Von der C++-Standardbibliothek wird das auch unterschiedlich gehandhabt, die Streams beispielsweise setzen intern Fehlerflags, können aber weiterverwendet werden. Dort treten aber auch relativ viele "Fehler" auf (EOF). In der STL wird das wieder ein wenig anders gehandhabt: z.B. wird bei std::vector::at() eine Exception geworfen, wenn man einen ungültigen Index verwendet.

12

11.11.2008, 20:06

Zitat von »"Nexus"«

Zitat von »"Nox"«

Besser ne Zombieklasse als nen Speicherwrack :lol:.
Naja, man kann durch Zombies auch leicht Memory Leaks haben. Oder Speicherzugriffsfehler, wenn im Destruktor wieder versucht wird, Speicher freizugeben, der nie angefordert wurde

wie denn das? delete(NULL) verursacht afaik keinen fehler, und ein eigenes Speichermanagement sollte doch normalerweise gegen solche Fehler abgesichert sein, oder?
Und wenn mir irgendjemand damit kommen will, das eventl. ja zeiger noch wilde Zeiger sind, wenn der Konstruktor vor ihrer Initialisierung abbricht (es sei mal dahingestellt ob durch throw oder return), dann sag ich ihm, das man alle kritischen Membervariablen (und das sind in demfall auch Zeiger) einer Klasse am besten in der Initialisierungsliste auf ungefährliche defaultwerte (in dem Fall NULL) setzt.

13

11.11.2008, 20:12

In "Effektiv C++" gibt es dazu auch ein nettes Kapitel, unter anderem darüber, das Smartpointer Speicherlecks in Konstruktoren die Exceptions werfen, vermeiden können.
Lieber dumm fragen, als dumm bleiben!

14

11.11.2008, 22:05

In Konstruktoren richtig aufzuräumen kann aber ohne Exceptions (gekoppelt mit RAII) ziemlich mühsam werden, vor allem wenn temporär Speicher angefordert wird, und das mehrmals. Das artet schnell zu einer If-Orgie aus und ist entsprechend fehleranfällig.

Das Problem bei Konstruktoren ohne Exceptions ist auch, dass man nicht direkt sieht, wenn etwas schiefgelaufen ist. Um den Fehler anzuzeigen, gibt es mehrere Möglichkeiten, beispielsweise als Flag-Membervariable der Klasse. Auf diese muss man jedoch immer explizit prüfen und kann den Fehler ignorieren, was bei Exceptions nicht geht.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

15

12.11.2008, 08:16

Zitat von »"Databyte"«

Mal ne allgemeine Frage: Wann sollte ich Exeptions benutzen und wann return-werte ?


Ich sehe das auch so, dass man exceptions wirklich nur in Ausnahmefällen benutzt. Und dann um dem Benutzer der Klasse (oder Funktion) zu sagen, dass etwas geschehen ist und man jetzt nicht weiss, was er machen soll.

Sprich, wenn du einen Loader von Texturen hast, und man da einen Pfad angeben kann, wo eine Textur zum laden ist und du das jetzt nicht laden kannst, dann schmeiss ne exception, dass du die nicht laden konntest und nicht weisst, was du machen sollst. Also überträgst du die Verantwortung dem, der dir den falschen Pfad gegeben hat. (Der kann ja dann die exception einfach fangen und z.B ein Dummy Objekt erzeugen).
Du fragst dich jetzt warum nicht gleich ein Dummy Objekt erzeugen..
Ganz einfach, warum solltest du? - Das ist nicht die Aufgabe des Loaders und wenn du das jetzt machen würdest, dann würde sich das Programm sich in meinen Augen einfach falsch verhalten, weil es etwas macht, dass ich gar nicht will (respektive ich ihm gesagt habe, dass er machen soll..)

Ich hasse es zum Beispiel, wenn ich etwas mit der WinAPI mache und dann (wie sich am Ende herausstelt) etwas falsch gelaufen ist, aber ich davon rein gar nichts mitbekomme, weil die WinAPI dann einfach nichts macht (was manchmal auch das richtige sein kann..). Da habe ich lieber eine harte exception an den Kopf geworfen, dass ich da Mist gemacht habe und wenigstens eine Chance habe es zu korigieren.


Zitat

In Konstruktoren richtig aufzuräumen kann aber ohne Exceptions (gekoppelt mit RAII) ziemlich mühsam werden, vor allem wenn temporär Speicher angefordert wird, und das mehrmals. Das artet schnell zu einer If-Orgie aus und ist entsprechend fehleranfällig.


Genau. Darum heisst es alles, was eine Resource ist in eine RAII Klasse packen, die anständig programmieren und dann sind auch exceptions aus dem Konstruktor kein Problem mehr.

Beneroth

Alter Hase

Beiträge: 969

Wohnort: Schweiz

Beruf: Software Entwickler

  • Private Nachricht senden

16

12.11.2008, 09:22

Zitat von »"Nox"«

Ich habe mir sagen lassen, dass throws in Konstruktoren zwar möglich, aber nicht wünschenswert sind ;) . Bemühe mal die Suchmaschine deiner Wahl zu dem Thema.


Ok, aber dass ist noch der einzige Verwendungszweck denn ich wirklich in denen sehe...

Zitat von »"drakon"«


Ich sehe das auch so, dass man exceptions wirklich nur in Ausnahmefällen benutzt. Und dann um dem Benutzer der Klasse (oder Funktion) zu sagen, dass etwas geschehen ist und man jetzt nicht weiss, was er machen soll.

Sprich, wenn du einen Loader von Texturen hast, und man da einen Pfad angeben kann, wo eine Textur zum laden ist und du das jetzt nicht laden kannst, dann schmeiss ne exception, dass du die nicht laden konntest und nicht weisst, was du machen sollst. Also überträgst du die Verantwortung dem, der dir den falschen Pfad gegeben hat.

Ok, aber für mich ist das nicht unbedingt eine Ausnahme, das ist ein Fall mit dem man rechnen muss, bei User Eingaben sind ja fast immer möglichen Falsch-Eingaben zu erwarten.

Exception sind sauberer weil sie den Programmierer zwingen diese aufzufangen während der return-Wert sehr einfach ignoriert werden kann.

Aber anderseits finde ich doch dass einem C++-Programmierer (theoretisch) eine gewisse Mündigkeit zugesprochen werden sollte so dass er wissen sollte wie und warum er das benutzt.

Klar dazu muss die Sache schön dokumentiert sein, aber dass muss bei Exceptions ebenfalls der Fall sein in C++.

So, was bleibt also noch, ausser dass einige Leute gern mehr OOP-mässig à la Java / C# programmieren und aus persönlicher Vorliebe lieber Exception benutzen, aber sonst?

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

17

12.11.2008, 09:32

Zitat

Ok, aber für mich ist das nicht unbedingt eine Ausnahme, das ist ein Fall mit dem man rechnen muss, bei User Eingaben sind ja fast immer möglichen Falsch-Eingaben zu erwarten.


User ja, aber nicht der Benutzer der Funktion. Da ist es dann die Aufgabe des Programmierers der Applikation dafür zu sorgen, dass der User richtig informiert wird, oder halt ein Dummy Objekt geladen wird und nicht die des Programmierers der Funktion (auch wenn das die gleichen sind..)

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

18

12.11.2008, 14:47

Nun mal eine ehrlich Meinung von mir: Ich hasse alle Menschen abgrundtief, die der Meinung sind mir per Exception mitteilen zu müssen, dass eine Datei nicht geladen werden konnte. Es reicht ein einfaches NULL oder sonstiger Fehlerwert, aber warum sind manche Menschen der Meinung aller Welt diese try-catch-Blöcke aufs Auge drücken zu müssen? Wenn etwas nicht geladen werden konnte, dann gibt man vielleicht ne Logmessage aus o.ä., aber schmeißt nicht wie ein Irrer mit exceptions umsich :!:

P.S: persönliche Meinung. Immerhin programmiere ich C++ nicht um mich bevormunden zu lassen :roll:
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

19

12.11.2008, 15:36

Exceptions dienen in C++ nicht der Ressourcenverwaltung. Dazu gehoert z.B. die Dateiverwaltung und IO-Operationen. Java und C# gehen da einen anderen Weg. Zwar kann man in C++ auch so programmieren und es ist vielleicht standardkonform (alles was mein Kompiler uebersetzt ist das meist, aber es gibt viel grauenhaftes, was standardkonform ist), aber es ist nicht idiomatisches C++. Anderes Beispiel: Setzen eines Pixel ausserhalb eines Bildes.

Ueber Bibliotheksgrenzen hinweg sollten auch keine Exceptions geworfen werden.

20

12.11.2008, 16:56

@Nox
ticpp benutzt Exceptions und die sind irre praktisch. Wenn ich eine XML-Datei lade, habe ich vielleicht nicht Lust, von jedem node zu prüfen ob er existiert. Ich sage einfach, dass alles vorhanden sein muss und die Datei sonst nicht geladen werde kann.
Dann bau ich einen try-Block um die gesamte Ladeoperation und falls irgendetwas nicht stimmt, krieg ich eine Exception mit einer Fehlerbeschreibung geliefert. Bequemer kann es doch gar nicht sein :)
Die zweite Möglichkeit wäre, immer zu prüfen ob das Element oder Attribut überhaupt existiert um keine Nullpointer zu dereferenzieren. Das ist umständlich, bläht den Code auf und man vergisst sehr schnell etwas. Und an solchen Stellen schmiert das Programm dann einfach ab, ohne dass du weißt warum.
Wenn ein Element nur optional in der Datei ist, kann man dass dann immer noch separat checken und entsprechend reagieren.

Klar, nur wegen einer Funktion einen try und catch Block zu schreiben ist umständlich, aber im Fall von XML Dateien gibt es nix besseres als Exceptions, die kommen, wenn die Datei nicht geöffnet werden konnte ;-)


Und in meinem Spiel verwende ich auch manchmal Exceptions, für kritische Fehler. Ich meine, wenn z.B. das Level nicht geladen werden konnte, muss man nicht in einer halb initialisierten Welt rumlaufen, und dann in der Logdatei nach irgendwelchen Fehlermeldungen suchen. Dann kommt per Exception ein kritischer Fehler, auf den man dann reagieren MUSS. Das ist ja grad der Vorteil von ihnen :D
Lieber dumm fragen, als dumm bleiben!

Werbeanzeige