2017-08-11 3 views
0

Ich versuche, Fehlercode aus dem Konstruktor zurückzugeben, da der Konstruktor keinen Fehlercode zurückgibt, habe ich versucht, eine Ausnahme auf den Konstruktor zu setzen. Dann gebe ich im catch-Block meinen passenden Fehlercode zurück. Ist dies eine geeignete Methode, um Fehlercode vom Konstruktor zurückzugeben?Wie man Fehlercode vom Konstruktor zurückgibt?

#include <exception> 
#include <iostream> 

class A { 
public: 
    A() { throw std::runtime_error("failed to construct"); } 
}; 

int main() { 
    try { 
    A a; 
    } catch (const std::exception& e) { 
    std::cout << "returining error 1 \n"; 
    return 1; 
    } 

    return 0; 
} 
+1

Für mich ist es eine gute Übung, den Konstruktor noexcept zu machen ... Vielleicht könnte ein guter Weg, um einen Zustand auf das Objekt wie: ungültig. Ich bin auf der Suche nach einer besseren Antwort sowie –

+3

Verwenden Sie einfach Ausnahmen überall. Fehlerrückgabewerte haben alle möglichen Probleme, insbesondere werden sie zu leicht ignoriert. –

+3

Ja, Konstruktor sollte entweder ein gültiges Objekt erstellen oder eine Ausnahme auslösen. – VTT

Antwort

0

Es gibt keine Möglichkeit, dies zu tun. Der beste Weg wäre wahrscheinlich, eine statische init() Methode zu haben, die eine Instanz der Klasse zurückgibt und den Konstruktor privat macht. Sie könnten den Großteil der Konstruktion aus der init-Methode machen und einfach einen Fehlercode zurückgeben.

+0

Leider funktioniert eine init() -Methode nicht für viele Klassen, insbesondere nicht für Member mit Konstruktoren, die Parameter verwenden. –

+0

Nicht sagen, ich stimme der Antwort zu, aber für die Aufnahme könnte die Init-Funktion perfekt weitergeleitet variadic Vorlage Argument – lapinozz

+0

@lapinozz Eine init() -Funktion, mit welchen Parametern, muss im Körper eines Konstruktors aufgerufen werden, und so nichts initialisieren kann - Es kann nur zuweisen. –

7

Nach isocpp.org, die richtige Art und Weise der Fehler bei einem Konstruktor in C++ zu handhaben ist:

eine Ausnahme aus.

Es ist nicht möglich, Fehlercode zu verwenden, da Konstruktoren keine Rückgabetypen haben. Aber :

Wenn Sie nicht die Möglichkeit haben, Ausnahmen zu verwenden, die „am wenigsten schlechten“ Work-around ist das Objekt in einen „Zombie“ Zustand zu versetzen, durch eine interne Status-Bit, so dass das Objekt wirkt Einstellung irgendwie wie es tot ist, obwohl es technisch noch am Leben ist.

Aber Sie sollten wirklich Ausnahmen verwenden Fehler in Konstrukteuren zu signalisieren, wenn Sie können, wie gesagt:

In der Praxis der „Zombie“, was ziemlich hässlich wird. Sicherlich sollten Sie Ausnahmen gegenüber Zombie-Objekten bevorzugen, aber wenn Sie nicht die Möglichkeit haben, Ausnahmen zu verwenden, könnten Zombie-Objekte die "am wenigsten schlechte" Alternative sein.

0

Hängt davon ab, wie wahrscheinlich Sie einen solchen Fehler einschätzen und wie wichtig eine ordnungsgemäße Initialisierung für die weitere Programmausführung ist.

  • Wenn ein Fehler beim Initialisieren des Objekts als Ausnahme betrachtet wird (z. B. weil der Arbeitsspeicher nicht mehr ausreicht), wird eine Ausnahme ausgelöst.
  • Wenn es sich um einen erwarteten Fehler handelt, den Sie hier und jetzt behandeln möchten, setzen Sie das Objekt in einen fehlgeschlagenen/standardkonstruierten Status und erlauben dem Benutzer, den Fehlercode abzufragen (z. B. wenn std::fstream nicht in der Lage ist öffne einen Ordner). Dies ist besonders hilfreich, wenn Sie die Objektinitialisierung mit verschiedenen Parameterwerten wiederholen möchten.
  • Btw .: Wenn Sie sich für eine Ausnahme entscheiden, würde ich es wahrscheinlich nicht in einen Fehlercode verwandeln, es sei denn, Sie müssen unbedingt. Ausnahmen wurden speziell entworfen, damit Sie keine Fehlercodes manuell übergeben müssen.

    +0

    Sie können die Objektinitialisierung nicht wiederholen, zumindest nicht für dasselbe Objekt. –

    +0

    Der Nachteil von Fall 2 ist nun, dass Sie testen müssen: "Wurden Sie richtig initialisiert?" jedes Mal, bevor Sie das Objekt verwenden. Wird zu einem echten Mist. – user4581301

    +0

    @NeilButterworth: Vielleicht nicht im üblichen Sinne, aber ich spreche über die Initialisierung in einen nützlichen Zustand (zB wenn Sie Farm in Betracht ziehen, können Sie zuerst versuchen, es mit einem vom Benutzer bereitgestellten Dateinamen zu konstruieren, und falls dies fehlschlagen sollte auf eine Standarddatei zurückgreifen, auf die Sie mit open zugreifen) – MikeMB

    Verwandte Themen