Was ist die beste Technik für den Ausstieg aus einem Konstruktor auf einen Fehler in C++
Was ist die beste Technik für den Ausstieg aus einem Konstruktor auf einen Fehler in C++? Dies ist insbesondere ein Fehler beim öffnen einer Datei.
Danke für die Antworten. Ich bin eine Ausnahme zu werfen. Hier ist der code (weiß nicht, ob es die besten Weg, es zu tun, aber es ist einfach)
//Test to see if file is now open; die otherwise
if ( !file.is_open() ) {
cerr << "Failed to open file: " << m_filename << endl;
throw ("Failed to open file");
}
Denke ich an C++ ist, Sie müssen nicht zu erklären, geworfene exceptions in den Methoden-Deklarationen.
- Ich würde empfehlen, wirft eine std::runtime_error, oder zumindest ein std::exception, anstatt ein const char*.
- mögliche Duplikate von How to handle-Fehler im Konstruktor in C++?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der beste Vorschlag ist wohl was parashift sagt. Aber Lesen Sie meine Warnung beachten Sie die unter-wie auch bitte.
Sehen parashift FAQ 17.2
Ein Wort der Vorsicht mit dem werfen von Ausnahmen im Konstruktor:
Sehr vorsichtig, denn wenn eine Ausnahme ausgelöst wird, die in einem Konstruktor der Klasse Destruktor nicht aufgerufen wird. So müssen Sie vorsichtig sein, über die Destruktion Objekte, die Sie bereits gebaut, bevor die exception geworfen wird. Das gleiche Warnungen gelten für das exception handling im Allgemeinen, aber es ist vielleicht ein wenig weniger offensichtlich, wenn es mit einem Konstruktor.
Protected/Private Konstruktoren mit CreateInstance-Methode:
Anderen Weg, um dieses ist, um Ihren Konstruktor auf private oder protected, und eine CreateInstance-Methode, können Fehler zurückgeben.
Können Sie eine Ausnahme werfen, wie andere erwähnt haben, oder Sie können auch umgestalten von code, so dass der Konstruktor nicht scheitern kann. Wenn, zum Beispiel, Sie arbeiten an einem Projekt, wo Ausnahmen deaktiviert sind oder nicht, dann ist letzteres die beste option.
Machen ein Konstruktor, der nicht scheitern kann, Umgestaltung des Codes, die potenziell scheitern in einer
init()
- Methode und den Konstruktor tun so wenig Arbeit wie möglich, und dann müssen alle Benutzer der Klasse zu nenneninit()
sofort nach dem Bau. Wenninit()
fehlschlägt, können Sie die Rückgabe ein Fehlercode. Stellen Sie sicher, dass dieses Dokument in Ihrer Klasse Dokumentation!Natürlich, das ist etwas gefährlich, da Programmierer möglicherweise vergessen zu nennen
init()
. Der compiler kann nicht erzwingen, also seien Sie vorsichtig und versuchen, Ihren code fail-schnell, wenninit()
ist nicht genannt.In der Regel sollten Sie eine Ausnahme werfen. Die alternative ist, einige halb-richtig konstruiert-Objekt, das der Benutzer hat, um zu testen, irgendwie, das Sie unweigerlich scheitern zu tun.
Wenn das Objekt, das Sie konstruieren, ist ungültig, wegen der Fehler, und muss entsorgt werden durch den Anrufer, dann haben Sie ziemlich viel haben, um eine exception zu werfen. Dies ermöglicht es dem compiler durchführen die korrekte Freigabe von Ressourcen.
(Schreiben von exception-sicher Konstruktoren erfordert ein wenig Sorgfalt-kurz, Sie müssen verwenden Sie die Initialisierer-Listen, wo immer Sie können, anstatt den Konstruktor Körper-aber es ist kritisch, wenn Sie haben ein Fall wie dieser, wo das werfen einer exception ist eine bedeutende Möglichkeit.)
Wenn Sie das Objekt nach dem Fehler nicht seine Aktionen auszuführen - Sie haben zu werfen. Wenn Sie es können - melden Sie Fehler und änderungen der Konstruktion der Logik.
Ausnahme auslösen. Werfen Sie einen Blick hier für mehr Informationen: Handling-Fehler im Konstruktor
Gibt es nur 1 guter Weg, um zu beenden aus einem Konstruktor, der Fehler ist, dass zu stärken, ist eine Ausnahme.
Ist es wirklich ein Fehler? sind Sie versuchen, zu viel an den Konstruktor?
Oft Menschen versuchen und Rollen in einigen anfänglichen Interaktion in den Konstruktor, wie das hinzufügen den Dateinamen einer Datei Konstruktor. Erwarten Sie es, um die Datei zu öffnen, sofort oder sind Sie nur die Einstellung einiger Zustand, ist es anders-Datei.open(Dateiname), ist es ok, wenn es scheitert?
Das beste, was zu tun ist, um eine exception zu werfen. Das ist, was Sie dort für, und jeder Versuch, das Verhalten zu reproduzieren, die Sie erhalten, ist wahrscheinlich ein Fehler irgendwo.
Wenn Sie nicht verwenden können, eine Ausnahme, aus irgendeinem Grund, verwenden Sie
nothrow
. Das Beispiel im Standard -, 18.4.1.1 Ziffer 9, ist:Dies ist technisch eine form der Platzierung neue, aber es sollte wieder ein vollständig geformtes Objekt oder ein null-Zeiger ist, dass Sie brauchen, um zu testen, außer, dass niemand.
Wenn eine Klasse ein Objekt, das ist es aber nicht richtig initialisiert haben, können Sie ein Datenelement, das dient als ein flag, ob die Klasse sinnvoll ist oder nicht. Nochmal, niemand wird überprüfen Sie, dass die fahne in der live-code.
Bedenken Sie, dass, wenn Sie wirklich brauchen, um haben eine Zuweisung, die garantiert nicht zu scheitern, müssen Sie den Speicher vor der Zeit und verwenden Sie placement-new, und entfernen Sie alle Initialisierungen, die möglicherweise zu werfen, um eine andere routine, die jemand nicht nennen. Alles, was Speicher reserviert ausfallen kann, und insbesondere auf die mehr beschränkt, Arten von Systemen, die in der Regel nicht unterstützen Ausnahmen.
Wirklich, die Ausnahmen sind der beste Weg zu gehen.