Exception werfen
-
pumuckl schrieb:
Wieso exception-Objekt? Da kann genausogut ein int, char* oder sonstwas geflogen kommen und ins Netz gehn

Das sind Objekte (abgesehen von Referenzen).

-
ich hab das mal einfach mal übernommen:
#include <string> #include <exception> class ScriptException : public std::exception { // Attributes // private: int m_line; std::string m_message; // Constructors // public: ScriptException(std::string const& message, int line) : m_line(line) , m_message(message) { } // Methods // public: virtual const char* what() const { return m_message.c_str(); } std::string const& get_message() const { return m_message; } int get_line() const { return m_line; } };und bekomm beim compiliern aber ien paar fehlermeldungen....
ScriptException.cpp 24: error: looser throw specifier for 'virual const char* ScriptException::what() cont' ScriptException.cpp 6: error: looser throw specifier for 'virtual ScriptException::~ScriptException()'
-
pumuckl schrieb:
Eben das ist das Problem. Du weißt nur dass du was gefangen hast, nicht was du gefangen hast, kannst es also nicht weiterverwenden. Wenn du dagegen von std::exception abgeleitet hast kannst du immerhin noch what() aufrufen:
Ach so war das gemeint ok. Aber wenn ich nicht erben lasse, aber trotzdem eine Klare Linie einhalte geht das ja im Grunde auch.
Ich hab folgende Aufstellung in meiner Klasse:
class e_MyExceptionBase { Konstruktor(); Operator=; Destruktor; Copykonstruktor; const char* what() const; };Das is ein Schema meienr Basisklasse von ihr erben alle Kategorieklassen (wie Memory und Operation) die dann ihrerseits Basis für Detail Exceptions sind (OutOfMemory zb) und die sehen dann bei mir so aus:
class e_MyExceptionBase_Memory { Konstruktor(); Operator=; Copykonstruktor; };Funktioniert bei mir ganz gut und am ende können bei mir ja nur 2 exceptions rauskommen eine std::exception oder eine e_MyExceptionBase.
-
Hat es einen Grund, wieso du eigene Kopierkonstruktoren und Zuweisungsoperatoren definierst? Verwaltest du dynamischen Speicher oder sonstige Ressourcen in deinen Exceptions?
-
Nexus schrieb:
Hat es einen Grund, wieso du eigene Kopierkonstruktoren und Zuweisungsoperatoren definierst? Verwaltest du dynamischen Speicher oder sonstige Ressourcen in deinen Exceptions?
Ja. Meine Base Exception hat einen char* in dem die Nachricht liegt. Die ganzen erbenden klassen schleifen in ihrem operator= und Copykonstruktor alles zur Basisklasse durch.
-
Xebov schrieb:
Ja. Meine Base Exception hat einen char* in dem die Nachricht liegt. Die ganzen erbenden klassen schleifen in ihrem operator= und Copykonstruktor alles zur Basisklasse durch.
Warum kein std::string?
-
Shade Of Mine schrieb:
Xebov schrieb:
Ja. Meine Base Exception hat einen char* in dem die Nachricht liegt. Die ganzen erbenden klassen schleifen in ihrem operator= und Copykonstruktor alles zur Basisklasse durch.
Warum kein std::string?
Ich wolte unnötiges Speicherholen vermeiden. Hab mich mit den strings mal auseinandergesetzt, und gelesen das für die ausgabe das Strings als CString nochmal Speicher geholt wird um den CString zu bauen, das wollte ich so eigentlich nicht haben, weil ich auf de reinen seite einheitlich mit den exceptions aus der std cStrings ausgeben wolte und auf der anderen Seite auch eigene Exceptions schmeiße wenn ich ein std::bad_alloc auffange, weis nicht ob meine überlegung so Sinnvoll ist oder nicht, ich fand sie auf jedenfall nicht schlecht und hab sie deshalb so umgesetzt.
-
Xebov schrieb:
Ich wolte unnötiges Speicherholen vermeiden.
Dann schreib dir eine passende string klasse.
Man fasst rohen speicher einfach nicht haendisch an.
-
Shade Of Mine schrieb:
Xebov schrieb:
Ich wolte unnötiges Speicherholen vermeiden.
Dann schreib dir eine passende string klasse.
Man fasst rohen speicher einfach nicht haendisch an.
Der aufwand würde sich nicht lohnen. Der Konstruktor nimtm die Nachricht entgegen und holt den Speicher zum reinstopfen und der Destruktor gibt ihn wieder frei, ich sehe da ehrlich gesagt keinen wirklichen Grund für eine Extra Klasse die am Ende ja auch nichts anderes macht.
-
Shade Of Mine schrieb:
Xebov schrieb:
Ich wolte unnötiges Speicherholen vermeiden.
Dann schreib dir eine passende string klasse.
Man fasst rohen speicher einfach nicht haendisch an.
boar... es geht um exceptions - ich weiß ja nicht, wie ihr programmiert, aber bei mir ist es eher die ausnahme, dass exceptions fliegen - also muss ich mir da echt 0 gedanken um performance machen - weil das ohnehin meist heißt, dass irgendwas nicht geht/ging...
bb
-
Aua!!! Wer hat mir die Exception an den Kopf geworfen? Passt mal besser auf!!!

-
unskilled schrieb:
boar... es geht um exceptions - ich weiß ja nicht, wie ihr programmiert, aber bei mir ist es eher die ausnahme, dass exceptions fliegen - also muss ich mir da echt 0 gedanken um performance machen - weil das ohnehin meist heißt, dass irgendwas nicht geht/ging...
Kein Mensch redet von performance...
@Xebov:
Eine string klasse mit minimalen speicher verbrauch ist immer nuetzlich - und sie zu schreiben ist weniger aufwendig als bei jeder exception klasse immer die ganzen operatoren zu definieren.komponenten wie zB strings oder aehnliches zu schreiben ist idR deutlich weniger aufwand als die funktionalitaet immer doppelt und dreifach zu schreiben

-
Shade Of Mine schrieb:
Kein Mensch redet von performance...
@Xebov:
Eine string klasse mit minimalen speicher verbrauch ist immer nuetzlich - und sie zu schreiben ist weniger aufwendig als bei jeder exception klasse immer die ganzen operatoren zu definieren.komponenten wie zB strings oder aehnliches zu schreiben ist idR deutlich weniger aufwand als die funktionalitaet immer doppelt und dreifach zu schreiben

Ja das is natürlich ein Argument. Wobei Copykonstruktor und operator alles nur durchreichen, die Arbeit selbst macht allein der Copykonstruktor/operator der Basisklasse. Ich werds aber mal in Betrachtziehen da ich in etlichen klassen nur einfache CStrings speichern muß, da könnte ne Kapselung nicht schaden.
unskilled schrieb:
boar... es geht um exceptions - ich weiß ja nicht, wie ihr programmiert, aber bei mir ist es eher die ausnahme, dass exceptions fliegen - also muss ich mir da echt 0 gedanken um performance machen - weil das ohnehin meist heißt, dass irgendwas nicht geht/ging...
Es geht dabei weniger um Performance, wenn ich generell Exceptions werfe und welche dabei sind die OutOfMemory bedeuten ist es schon vorteil haft in diesem Fall sowenig Speicher wie Möglich zu holen um zu vermeiden das das erstellend er Exception selbst fehlschlägt.
-
Xebov schrieb:
Ich wolte unnötiges Speicherholen vermeiden. Hab mich mit den strings mal auseinandergesetzt, und gelesen das für die ausgabe das Strings als CString nochmal Speicher geholt wird um den CString zu bauen, ...
Verstehe ich dich richtig, dass du nicht wolltest, wenn du die Funktion
std::string::c_str()verwendest, dass hier zusätzlicher Speicher verbraucht wird? Ich hoffe, dir ist bewusst, dass die meistenstd::stringImplementationen hier nicht zusätzlichen Speicher allokieren, sondern den eigenen Speicher intern immer um +1 grösser halten und eine '\0' am Ende reinspeichern.Das was du hier machst, würde ich als PMO bezeichnen. Du probierst etwas zu optimieren, wo du noch gar keine Ahnung hast, ob es wirklich schlechter läuft.
Grüssli
-
Dravere schrieb:
Verstehe ich dich richtig, dass du nicht wolltest, wenn du die Funktion
std::string::c_str()verwendest, dass hier zusätzlicher Speicher verbraucht wird? Ich hoffe, dir ist bewusst, dass die meistenstd::stringImplementationen hier nicht zusätzlichen Speicher allokieren, sondern den eigenen Speicher intern immer um +1 grösser halten und eine '\0' am Ende reinspeichern.So wie ich das mal verstanden hatte garanteirt der std:string doch nicht das die zeichen in der Reihenfolge eines CStrings im Speicher liegt und erstellt den CString nur bei bedarf? Oder war das Blödsinn?
-
Shade Of Mine schrieb:
unskilled schrieb:
boar... es geht um exceptions - ich weiß ja nicht, wie ihr programmiert, aber bei mir ist es eher die ausnahme, dass exceptions fliegen - also muss ich mir da echt 0 gedanken um performance machen - weil das ohnehin meist heißt, dass irgendwas nicht geht/ging...
Kein Mensch redet von performance...
wenn man performance nicht nur über laufzeit definiert, sondern auch speicherverbrauch mitzählt, dann schon!
@Xebov: Ja, der Standard garantiert das nicht - aber ich habe bisher noch nie eine Implementation gesehen, wo der string beim c_str() umkopiert wird... ist ja auch nicht wirklich sinnvoll...
und trotzdem ist eine solche klasse ab und an ganz hilfreich - aber das ist und bleibt eine exception - eine ausnahme - was bringt es dir, wenn dein programm in ausnahmen weit unter 1kb speicher weniger braucht?
bb
-
Xebov schrieb:
So wie ich das mal verstanden hatte garanteirt der std:string doch nicht das die zeichen in der Reihenfolge eines CStrings im Speicher liegt und erstellt den CString nur bei bedarf? Oder war das Blödsinn?
Ich frage mich nach wie vor, wer für die Speicherverwaltung zuständig sein sollte, wenn der
std::stringeinen neuen C-String erstellt.Xebov, hattest du wirklich mal eine OutOfMemoryException? Aufgrund welcher Gegebenheiten wirfst du diese? In C++ ist für zu wenig Speicher eigentlich
std::bad_alloczuständig, ansonsten hat deine Exception vielleicht nicht den richtigen Namen...
-
Nexus schrieb:
Xebov, hattest du wirklich mal eine OutOfMemoryException? Aufgrund welcher Gegebenheiten wirfst du diese? In C++ ist für zu wenig Speicher eigentlich
std::bad_alloczuständig, ansonsten hat deine Exception vielleicht nicht den richtigen Namen...Hatte noch nie, meine Programme verbrauchen noch viel zu wenig Speicher als das das jemals passieren könnte. Ich werfe sie wenn ich in einigen programmteilen std::bad_alloc auffange, ich gliedere die Exception quasi ein, ich fange sie auf und werfe meine eigene an der Stelel weiter, aber nicht imemr, außerdem verwende ich sie für DX Fehlercodes die das selbe aussagen, wieso fragst du?
-
Xebov schrieb:
wieso fragst du?
Weil es mich wundert, dass du dir die Mühe machst, eine fast nie auftretende Exception wie
std::bad_allocnoch selbstständig weiterzuleiten. Ganz konsequent wirst du das wahrscheinlich nicht machen können...Hast du etwas gegen die Exception-Hierarchie der Standardbibliothek?
-
Nexus schrieb:
Xebov schrieb:
wieso fragst du?
Weil es mich wundert, dass du dir die Mühe machst, eine fast nie auftretende Exception wie
std::bad_allocnoch selbstständig weiterzuleiten. Ganz konsequent wirst du das wahrscheinlich nicht machen können...Hast du etwas gegen die Exception-Hierarchie der Standardbibliothek?
Nein ich habe dagegen nichts. Ich bastel ne kleine Engine zusammen und die kommt halt aus einem Guß nun habe ich aber 2 verschiedene OutOfMemory Meldungen, einmal nen fehelrcode aus DX und einmal ne std::bad_alloc aus der std, und die leite ich beide auf eine eigene OutOfMemory Exception um.
Konsequent bin ich dabei ind er Tat nicht, da sis aber absicht, ich leite std::bad_alloc nur da um wo es sinn macht, dh Hauptsächlich wenn sich Interne Daten vergrößern, wenn aber Hauptteile "hochfahren" dann leite ich sie nicht um weil dann das Programm so oder so nicht weit käme.