Exception Klasse -> Konstruktor übergabe einer Konstante (define)

Skid

Erfahrenes Mitglied
Hallo zusammen,

ich habe in einem Programm eine Ausgabe von Fehlern mittels MessageBox integriert, die Fehlertext (MessageBox-Text) und eine Id (MessageBox-Caption) des Fehlers anzeigt. Die Id und der Text ist jeweils in einer separaten Header-Datei gespeichert und mittels Schlüsselwort "define" definiert, also etwa so:

Code:
#define ERR_WIN_STR	"Window error"
#define ERR_WIN_ID	"Error 0"

Jetzt habe ich mir überlegt, da die einzelne Ausgabe einer MessageBox je Fehler doch recht mühselig ist, einfach eine Exception zu werfen, die in der Main-Funktion "gefangen" wird und dort die jeweilige MessageBox ausgibt. Die Exception Klasse beinhaltet dabei den Text und die Id des Fehlers. Diese werden an die MessageBox weitergereicht.

Allerdings gibt es dabei ein Problem:
Der Konstruktor der Exceptionklasse erwartet eine Zeichenkette (char). Soweit ich jedoch weiß ist der Typ einer Konstante, die mit "define" definiert wurde, "TEXT". Ich könnte jetzt natürlich alle Fehler mit Text und ID als "const char[]" definieren, allerdings weiß ich nicht, ob das so - mal abgesehen von dem Aufwand - vorteilhaft ist ?

Hier der Auszug der Exceptionklasse:
Code:
class cException
{
	protected:
	private:
		//	Variables
		char * mMessage;
		char * mId;

	public:
		//	(De-)Constructor
		cException(char& pStrMessage, char& pStrId);
		virtual ~cException() {}

		//	Functions
		const char* fGetStr() { return mMessage;	}
		const char* fGetId() { return mId;		}
};

Hat jemand eine Idee oder Anregung?

Beste Grüße und vielen Dank,
SKiD.
 
Hi.
Der Konstruktor der Exceptionklasse erwartet eine Zeichenkette (char).
Das stimmt schonmal nicht. Ein Zeichenkette / String wäre "[const] char*".

Dein Konstruktor bekommt eine Referenz auf ein einzelnes Zeichen, keine Zeichenkette.
Soweit ich jedoch weiß ist der Typ einer Konstante, die mit "define" definiert wurde, "TEXT".
Ein define mittels Präprozessor besitzt keinen Typ.

Du ersetzt den Token ERR_WIN_STR durch das Stringliteral "Window error". Der Typ eines Stringliterals ist "const char*" bzw. "const char[]".
Ich könnte jetzt natürlich alle Fehler mit Text und ID als "const char[]" definieren
Das ist unnötig, denn das sind sie bereits.

Hat jemand eine Idee oder Anregung?
- defines sind in C++ verpönt. es gibt bessere Alternativen (inline Funktionen / Konstanten)
- berichtige die Parametertypen des Konstruktors
- berichtige den Typ der Attribute (const)
- schau dir Boost.Exception und Boost.System an
- erbe von std::exception oder einer Unterklasse

Gruß
 
Hallo deepthroat,

vielen Dank für deine Antwort!

Das stimmt schonmal nicht. Ein Zeichenkette / String wäre "[const] char*".

Dein Konstruktor bekommt eine Referenz auf ein einzelnes Zeichen, keine Zeichenkette.

Das war natürlich Käse. Du hast recht!

- defines sind in C++ verpönt. es gibt bessere Alternativen (inline Funktionen / Konstanten)

Warum sind defines verpönt?
//EDIT: Ich schätze mal, dass zielt auf die Typsicherheit hin? "const char" wäre ja natürlich um einiges sicherer als meine Methode, mal abgesehen davon, dass der Compiler ohne Vorwarnung nicht einfach meine Variable überschreiben kann, ohne mich zu benachrichtigen.

- erbe von std::exception oder einer Unterklasse

Warum?
Da ich nur so eine Exception wirklich "werfen" und "fangen" kann?

- schau dir Boost.Exception und Boost.System an

Werde ich tun!

Ich habe gestern ziemlich lange nach irgendwelche Referenzen zu dieser Define-Direktive im Netz gesucht, die beschreibt, welchen Typ dieser Stringliteral nun genau hat und wie man richtig damit umgehen kann/soll. Leider war die Suche dahingehend weniger von Erfolg gekrönt. Wo liest du das nach? Selbst in der MSDN habe ich dazu nichts gefunden, bis auf die Standarderklärungen.
 
Zuletzt bearbeitet:
Hi.
Warum sind defines verpönt?
//EDIT: Ich schätze mal, dass zielt auf die Typsicherheit hin? "const char" wäre ja natürlich um einiges sicherer als meine Methode, mal abgesehen davon, dass der Compiler ohne Vorwarnung nicht einfach meine Variable überschreiben kann, ohne mich zu benachrichtigen.
Siehe z.B. http://www2.research.att.com/~bs/bs_faq2.html#macro
Warum?
Da ich nur so eine Exception wirklich "werfen" und "fangen" kann?
Du kannst auch eine eigene Exception Hierarchie entwerfen, aber (je nach Anwendungsfall) ist es ganz nützlich alle möglichen Ausnahmen mit "catch (const std::exception& e)" zu behandeln.

Siehe http://www.boost.org/community/error_handling.html
Ich habe gestern ziemlich lange nach irgendwelche Referenzen zu dieser Define-Direktive im Netz gesucht, die beschreibt, welchen Typ dieser Stringliteral nun genau hat und wie man richtig damit umgehen kann/soll.
Wie gesagt hat das überhaupt nichts mit der define Direktive zu tun. (die betrifft ja auch nur den Präprozessor).

Und dann ist ein Stringliteral natürlich ein String, ein String in C hat den Typ "char *". So kann man sich das erstmal vorstellen.

Ansonsten müßte man das im Sprachstandard nachschauen, ich habe auf die Schnelle nur folgendes Zitat gefunden:
2.13. Sttring literals

[...]An ordinary string literal has type “array of n const char” and static storage duration (3.7)

Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation- defined. The effect of attempting to modify a string literal is undefined.
Gruß
 

Neue Beiträge

Zurück