Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: C++ (auch C++0x und C++11) ::  Exception Practice  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
cooky451
Mitglied

Benutzerprofil
Anmeldungsdatum: 16.10.2010
Beiträge: 4840
Beitrag cooky451 Mitglied 21:45:12 01.02.2012   Titel:   Exception Practice            Zitieren

Hey,

ich würde ja eine Umfrage draus machen, aber das geht hier nicht. Na ja, Erklärungen sind ja auch ganz interessant.

Mich würde interessieren, wie ihr mit Exceptions umgeht. Üblicherweise erbt man ja von std::runtime_error, das macht wahrscheinlich jeder. (Oder man wirft gleich std::runtime_error) Aber:
- Wenn es zu der Exception einen Fehlercode gibt (z.B. bei socket Fehlern), kümmer ihr euch um den? Falls ja, übergebt ihr den einfach der Exception und schreibt der noch eine error_code() Methode? Oder baselt ihr vorher einen String mit dem Errorcode zusammen? Oder bastelt ihr den in der Exceptionklasse?
- Fangt ihr einfach std::runtime_error und gebt .what() aus? Oder macht ihr euch z.B. ganz viele verschiedene Exceptionklassen, sodass ihr beim Fangen schon in etwa wisst, was das für ein Fehler war? (socket_error, file_error, ..., std::runtime_error)

_________________
Sie sind nicht berechtigt unrechtmäßige Kopien dieses Datenträgers zu erstellen.™
seldon
Unregistrierter




Beitrag seldon Unregistrierter 21:51:28 01.02.2012   Titel:              Zitieren

Eigentlich ist es meistens nicht besonders elegant, von std::runtime_error zu erben; std::logic_error ist meistens angebrachter. Das "runtime" in "runtime_error" ist nicht als "Fehler zur Laufzeit" zu verstehen, sondern als "Fehler in der Laufzeitumgebung" - deswegen erben overflow_error und underflow_error von runtime_error, während invalid_argument, out_of_bounds etc. von logic_error erben - das meint "Fehler in der Programmlogik", also quasi "ein anderer Programmteil hat mir Unfug angedreht."

Die Unterscheidung ist allerdings ziemlich vage und nicht besonders praktisch. Meistens erbe ich von std::logic_error und fange std::exception (oder halt konkret den Exceptiontyp, den ich selbst definiert habe). Fehlercodes speichere ich ggf. natürlich als Zahl und nicht als String - das wär ja albern.
cooky451
Mitglied

Benutzerprofil
Anmeldungsdatum: 16.10.2010
Beiträge: 4840
Beitrag cooky451 Mitglied 22:00:41 01.02.2012   Titel:              Zitieren

seldon schrieb:
"Fehler in der Programmlogik"
Danke für den Tipp. Bei meinen Beispielen allerdings scheint mir runtime_error durchaus angebracht. (Sockets, Dateien)

seldon schrieb:
Fehlercodes speichere ich ggf. natürlich als Zahl und nicht als String - das wär ja albern.

Nun ja, dann musst du aber auch alle Exceptions unterschiedlich fangen. Denn ansonsten könne man auch einfach eine Basisklasse fangen, und in den jeweiligen Spezialisierungen einen vollständigen Fehlerstring zusammenbasteln.

Das hälst du nicht für wünschenswert?

_________________
Sie sind nicht berechtigt unrechtmäßige Kopien dieses Datenträgers zu erstellen.™
Mechanics
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.01.2012
Beiträge: 432
Beitrag Mechanics Mitglied 22:19:44 01.02.2012   Titel:              Zitieren

Ich versuche normal die möglichen Fehlerursachen in eigene Exceptions zu fassen und sie auch zu behandeln. Den String mit der Fehlermeldung kann ich dann in der Gui zusammenbauen. Etwas banales Beispiel, wenn ich eine Funktion aufrufe und weiß, sie kann eine IndexOutOfRange, eine DivisionByZero und eine InvalidParameter Exception schmeißen, dann kann ich an der Stelle wo ich sie aufrufe das auch abfangen, denn ich weiß normalerweise, woran das dann liegt, wenn so eine Exception kommt. Wenn ich den Fehler aber nicht im Griff habe, wird es etwas schwieriger. z.B. bei der Netzwerkkommunikation, wo 50 verschiedene Fehler kommen können. Dann reicht es aber vielleicht ersteinmal eine entsprechende NetworkCommunicationException zu schmeißen und dann weiß man, ok, bei der Kommunikation ist was schiefgelaufen und dann evtl. weiter nachforschen, z.b. über den Fehlercode, um dem Benutzer eine aussagekräftige Fehlermeldung (wie Passwort falsch oder Server nicht erreichbar) anzuzeigen.
seldon
Unregistrierter




Beitrag seldon Unregistrierter 22:51:31 01.02.2012   Titel:              Zitieren

cooky451 schrieb:

seldon schrieb:
Fehlercodes speichere ich ggf. natürlich als Zahl und nicht als String - das wär ja albern.

Nun ja, dann musst du aber auch alle Exceptions unterschiedlich fangen. Denn ansonsten könne man auch einfach eine Basisklasse fangen, und in den jeweiligen Spezialisierungen einen vollständigen Fehlerstring zusammenbasteln.

Die what()-Methode gibt's ja nach wie vor, und wenn ich den Fehlercode direkt brauche, kann ich mit std::exception eh nichts anfangen. Ich meine das etwa so:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Für diese Dinge benutze ich dann gerne X-Makros, um mir keine Gedanken
// um die Synchronisation zwsichen Fehlercode und Fehlermeldung machen zu müssen.

enum error_code {
  ERR_SUCCESS,
  ERR_FEHLER1,
  ERR_FEHLER2,
  ...
};

extern char const *const error_messages[];

// Hier nicht von std::logic_error, weil kein std::string gebraucht wird, um
// die Fehlermeldung aufzubewahren.

class my_exception : public std::exception {
public:
  my_exception(error_code ecode) : ecode_(ecode) { }
  virtual ~my_exception() throw() { }

  virtual error_code  code() const throw() { return ecode_; }
  virtual char const *what() const throw() { return error_messages[ecode_; }

private:
  error_code ecode_;
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Für diese Dinge benutze ich dann gerne X-Makros, um mir keine Gedanken
// um die Synchronisation zwsichen Fehlercode und Fehlermeldung machen zu müssen.

enum error_code {
ERR_SUCCESS,
ERR_FEHLER1,
ERR_FEHLER2,
...
};

extern char const *const error_messages[];

// Hier nicht von std::logic_error, weil kein std::string gebraucht wird, um
// die Fehlermeldung aufzubewahren.

class my_exception : public std::exception {
public:
my_exception(error_code ecode) : ecode_(ecode) { }
virtual ~my_exception() throw() { }

virtual error_code code() const throw() { return ecode_; }
virtual char const *what() const throw() { return error_messages[ecode_; }

private:
error_code ecode_;
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Für diese Dinge benutze ich dann gerne X-Makros, um mir keine Gedanken
// um die Synchronisation zwsichen Fehlercode und Fehlermeldung machen zu müssen.

enum error_code {
  ERR_SUCCESS,
  ERR_FEHLER1,
  ERR_FEHLER2,
  ...
};

extern char const *const error_messages[];

// Hier nicht von std::logic_error, weil kein std::string gebraucht wird, um
// die Fehlermeldung aufzubewahren.

class my_exception : public std::exception {
public:
  my_exception(error_code ecode) : ecode_(ecode) { }
  virtual ~my_exception() throw() { }

  virtual error_code  code() const throw() { return ecode_; }
  virtual char const *what() const throw() { return error_messages[ecode_; }

private:
  error_code ecode_;
};


Natürlich ist es eine andere (und nicht triviale) Frage, wann man Fehlercodes benutzen und wann man neue Exceptionklassen einführen sollte; die kann ich aber nicht pauschal beantworten.
nostdexcept
Unregistrierter




Beitrag nostdexcept Unregistrierter 23:01:41 01.02.2012   Titel:              Zitieren

Mechanics schrieb:
wie Passwort falsch oder Server nicht erreichbar
Warum sollte das eine Exception werfen? Solche erwarteten Fehler werden bei mir ohne Exceptions behandelt.
knivil
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.02.2009
Beiträge: 4495
Beitrag knivil Mitglied 23:18:08 01.02.2012   Titel:              Zitieren

Das leidige Thema. Such doch einfach im Forum.

_________________
If it were not for laughter, there would be no Tao.
Sie können einen Beitrag nicht so schnell nach Ihrem letzten absenden, bitte warten Sie einen Augenblick.
Mechanics
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.01.2012
Beiträge: 432
Beitrag Mechanics Mitglied 23:27:02 01.02.2012   Titel:              Zitieren

nostdexcept schrieb:
Mechanics schrieb:
wie Passwort falsch oder Server nicht erreichbar
Warum sollte das eine Exception werfen? Solche erwarteten Fehler werden bei mir ohne Exceptions behandelt.


Wo? Wenn es eine interne Funktion gibt, die irgendwas übers Netzwerk übertragen muss, hat sie keine "erwarteten Fehler" zu behandeln. Wenn die Netzwerkkommunikation nicht funktioniert hat, dann ist es eine Ausnahme von dem erwarteten Verhalten der Funktion und wird durch eine Exception weitergegeben. Behandeln könnte man sie dann z.B. in der GUI.
knivil
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.02.2009
Beiträge: 4495
Beitrag knivil Mitglied 00:36:27 02.02.2012   Titel:              Zitieren

Das erwartete Verhalten wird vom Device bestimmt und nicht vom Programmierer. Der Abbruch einer Netzwerkverbindung ist sehr wahrscheinlich.

_________________
If it were not for laughter, there would be no Tao.
Sie können einen Beitrag nicht so schnell nach Ihrem letzten absenden, bitte warten Sie einen Augenblick.
Mechanics
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.01.2012
Beiträge: 432
Beitrag Mechanics Mitglied 00:49:23 02.02.2012   Titel:              Zitieren

knivil schrieb:
Das erwartete Verhalten wird vom Device bestimmt und nicht vom Programmierer. Der Abbruch einer Netzwerkverbindung ist sehr wahrscheinlich.


Das ist keine Antwort. Die Frage ist, wo was behandelt wird. Exceptions sind eine Möglichkeit, Fehler zu behandeln. Die Funktion selbst sollte sie nicht behandeln, das wär ganz schlechtes Design. Die Fehler müssen nach oben gegeben werden. Viel mehr Möglichkeiten als return codes oder Exceptions gibts nicht. Bevor ich return codes verwende, verwende ich doch viel lieber Exceptions.
C/C++ Forum :: C++ (auch C++0x und C++11) ::  Exception Practice  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.