Hier ist meine Ausnahmeklasse:
%Vor% Die Boost-Ausnahmerichtlinien empfehlen, keine Objekte zu platzieren, die Speicher als Mitglieder meiner Ausnahmeklasse zuweisen. In diesem Fall verletzt die Verwendung von std::string
dies. Ich respektiere die Regel dafür, aber ich kann mir keinen Weg vorstellen, den what()
override zu implementieren, ohne std :: string zu verwenden, um den Speicher zu verwalten (im Gegensatz zu dem Anrufer, ihn für mich zu verwalten).
Ich könnte einen Puffer fester Größe als Mitglied verwenden und C-Bibliotheksfunktionen (wie snprintf()
) verwenden, um die Aufgabe zu erledigen, aber das ist nicht sehr idiomatisch für C ++ und daher keine ideale Lösung.
Ist dies eine geeignete Implementierung einer Ausnahmeklasse? Wenn nicht, welche Verbesserungen können gemacht werden?
Für das, was es wert ist, nehmen alle in <stdexcept>
definierten Ausnahmetypen std::string
als Argumente an. Dies könnte von den Bibliotheksdesignern so interpretiert werden, dass es "in Ordnung" ist. Ich denke, das Hauptargument dagegen ist, dass Sie, wenn Sie sich in einer Umgebung mit eingeschränktem Speicher befinden, möglicherweise keinen Speicher zuweisen können, um Ihre Ausnahme auszulösen.
Ausnahmen sollten vor einer möglichen Erschöpfung der Ressourcen während ihres Baus schützen. Die Verwendung von dynamischen Arrays in Exceptions ist nicht gut (es sei denn, es wird durch Zeiger ausgeführt und es gibt einen Rückfallplan, wenn die Zuweisung fehlschlägt). Die Verwendung von std::string
, um einige Informationen an den Benutzer zu übermitteln, ist doppelt so: Erstens ist es dynamisches Array, zweitens ist es meistens nutzlos - Funktion, die Exceptions wirft, kennt keine Umstände, um vernünftig zu erklären, warum es fehlgeschlagen ist.
Ausnahmen sollten nützliche Dinge wie Stack Tracing + Wiederherstellung von Funktionsparametern (wenn möglich) + ID zu einer externen Nachricht (z. B. dynamische Bibliotheksressource) tun, falls eine formatierte Low-Level-Nachricht für den Endbenutzer benötigt wird. Wenn Ausnahmen für den Endbenutzer gemacht werden, sollte es in Form einer kohärent formatierten Fehlermeldung von einer externen Zeichenkettentabellenvorlage (möglicherweise Hinzufügen einiger Laufzeitparameter) erfolgen. Wenn Exception verwendet wird, um das Debuggen zu erleichtern und es an den Entwickler zu machen, dann Stack-Trace, Funktionsparameter, Zustand der Maschine ist nützlich, einige hard-codierte allgemeine Zeichenfolge ist nicht.
EDIT: Es sieht so aus, als ob Sie versuchen, C ++ - Ausnahme-Wrapper um Windows-API-Aufrufe zu machen, bin ich richtig? Wenn ja, sollten Sie mehrere Dinge berücksichtigen:
dbghelp.dll
StackWalk64 () , SymFromAddr () und ähnliche Funktionen zum Generieren von visuell lesbarem Stapel-Trace (gerade Adresse sind auch zum Debuggen von Offsite nützlich) in Ausnahmekonstruktor; als Teil der privaten Daten der Klasse haben einen statischen Zeichenpuffer (erwägen Sie TLS wenn Multithreading)
what () gibt nur einen konstanten Zeiger auf diesen Puffer zurück.
in GetFormattedMessage () füllen Sie den Puffer aus (so wie Sie es gerade tun) (und eventuell von Unicode / wchars konvertieren, wenn Sie mit TCHARs arbeiten)
Als statisches Klassenmitglied wird der Puffer vor dem Auftreten einer Ausnahme im Stack vorallokiert.
Sie müssen den Speicher nicht verwalten, da er auf dem Stack zugewiesen ist. Sie kauen jedoch 1000 Bytes Stack-Speicherplatz (normalerweise keine große Sache)
es gibt jedoch nur einen Puffer für den Fehlertext, aber zu jedem Zeitpunkt sollte nur eine Ihrer benutzerdefinierten Ausnahmen existieren (denke ich?)
Tags und Links c++ exception-handling design exception