2010-11-22 15 views
0

Ich kann nicht scheinen, meinen Kopf herum zu bekommen, warum Leute sagen, dass C++ - Ausnahmen besser sind. Zum Beispiel habe ich eine Anwendung, die Funktionsobjekte von gemeinsam genutzten Objekten lädt, die in der Anwendung verwendet werden sollen. Was passiert, ist so etwas wie:Wie ändere ich meine Fehlerbehandlungsmethode

bool LoadFunctions() 
{ 
    //Get Function factory. 
    FunctionFactory& oFactory = GetFunctionFactory(); 
    //Create functions from the factory and use. 
} 

FunctionFactory& GetFunctionFactory() 
{ 
    //Get shared object handle. 
    void* pHandle = dlopen("someso.so"); 

    //Get function ptr for Factory getter. 
    typedef FunctionFactory* (*tpfFacGet)(); 
    tpfFacGet pF = static_cast<tpfFacGet>(dlsym(pHandle, "GetFactory")); 

    //Call function and return object. 
    return *((*pF)()); 
} 

Jetzt ist es einfach zu sehen, dass viele Dinge schief gehen können. Wenn ich es so machen würde, wie ich es immer tue, würde ich Zeiger anstelle von Referenzen zurückgeben, und ich würde prüfen, ob sie NULL sind und eine Fehlermeldung ausgeben und herauskommen, wenn sie nicht wären. Auf diese Weise weiß ich, wo die Dinge schief gelaufen sind, und ich kann sogar versuchen, mich davon zu erholen (d. H. Wenn ich die Fabrik erfolgreich geladen habe und nur eine einzige Funktion nicht laden kann, fahre ich möglicherweise fort). Was ich nicht verstehe, ist, wie man Ausnahmen in einem solchen Szenario verwendet und wie man das Programm wiederherstellt, anstatt eine Fehlermeldung und ein qutting zu drucken. Kann mir jemand sagen, wie ich das auf C++ so machen soll?

Antwort

2

Wir brauchen nicht einmal Rückkehrcodes. Wenn ein Problem auftritt, sollte es in der Ausnahme sein.

int main() 
{ 
    try 
    { 
     LoadFunctions(); 
     // if we're here, everything succeeded! 
    } 
    catch(std::exception _e) 
    { 
     // output exception message, quit gracefully 
    } 

    // IRRESPECTIVE OF SUCCESS/FAILURE WE END UP HERE 

    return 0; 
} // eo main 

EDIT:

Okay, können so sagen, dass Sie eine alternative Methode der Ladefunktionen haben sollte LoadFunctions() scheitern. Sie könnten versucht sein, das im Handler catch anzurufen, aber auf diese Weise werden Sie schnell mit einer großen Menge verschachtelter Ausnahmebehandler enden, was die Dinge nur verkompliziert.

So jetzt kommen wir auf die Frage Design. LoadFunctions sollte erfolgreich sein, wenn Funktionen geladen sind, und eine Ausnahme auslösen, wenn dies nicht der Fall ist. In diesem hypothetischen Beispiel einer alternativen Methode zum Laden von Funktionen sollte dieser Aufruf innerhalb der LoadFunctions Methode erfolgen. Diese alternative Methode muss für den Aufrufer nicht sichtbar sein.

Auf der obersten Ebene wir entweder mit Funktionen am Ende, oder wir tun es nicht. Schreiben gute Ausnahmebehandlung, meiner Meinung nach ist über graue Flächen loszuwerden. Die Funktion hat getan, was gesagt wurde, oder nicht.

+0

"// Ausnahmebedingungsnachricht, elegant beenden" - Dies ist genau die Art von Sache, die ich nicht verstehe. Was, wenn ich nicht aufhören will? Was mache ich dann? – nakiya

+0

Wenn Sie nicht aufhören möchten, schreiben Sie einfach, was Sie stattdessen im catch-Block tun möchten. – Simone

+0

Es ist so einfach, und dann wissen Sie, dass Ihre GetFunctionFactory-Funktionen immer ein konsistentes Ergebnis zurückgibt, so dass es nicht jedes Mal überprüft werden muss, wenn es verwendet wird. – daramarak

0

Es ist, wie Sie sagen, eine Menge, die schief gehen können. Sie werden dort übrigens keine schlechte Besetzung finden. Wenn das Symbol existiert, aber nicht der Typ ist, auf den Sie es anwenden, werden Sie später einen bösen Schock bekommen.

Wenn Sie Ausnahmen zu vermeiden sind, werden Sie irgendwo müssen die Fehler melden. Wie Ihre LoadFunctions und GetFunctionFactory() nicht wissen, wie Sie den Fehler behandeln möchten (loggen Sie es aus? Drucken Sie es auf stderr aus? Stellen Sie ein Meldungsfeld auf?) Das einzige, was es tun kann, ist den Fehler zu generieren.

Ein gemeinsamer Weg in C zu tun ist in einem Parameter zu übergeben, in denen er den Fehler setzen kann, wenn man auftritt, und für jede Funktion auf „prüfen“ Erfolg, bevor Sie fortfahren. Dies kann den Fluss ziemlich schwierig machen.

Das C++ Konzept der „werfen“ die Ausnahme bedeutet, dass Sie (oder Referenz) durch jede Funktion keinen Zeiger halten müssen vorbei. Wo der Fehler auftritt, generieren Sie ihn und "werfen" ihn - ein bisschen wie "schreien". Dies führt dazu, dass der gesamte Code (außer Bereinigung in Destruktoren) angehalten wird, bis ein Catcher gefunden wird, der den Fehler so behandelt, wie er benötigt wird.

Beachten Sie, dass Ausnahmen nur allgemein Fehler verwendet werden, zu handhaben, nicht einen normalen Vorgang wie „Dateiende“ zu begegnen, wenn dies der Weg ist, wissen Sie, ein Lese abgeschlossen hat.

0

Die Verwendung von Ausnahmen anstelle von Rückgabewerten (oder einer anderen Methode) soll nicht das Verhalten des Codes ändern, sondern nur, wie er geschrieben und organisiert wird. Das bedeutet im Wesentlichen, dass Sie zuerst entscheiden, was Ihre Wiederherstellung eines bestimmten Fehlers ist, sei es eleganter oder weniger, dann schreiben Sie den Code, um das auszuführen. Die meisten erfahrenen Programmierer (alle praktisch) stimmen zu, dass Ausnahmen eine viel bessere Methode als Rückgabewerte sind. Sie können den großen Unterschied in kurzen Beispielen einiger Funktionen nicht sehen, aber in realen Systemen von Tausenden von Funktionen und Typen würden Sie es klar sehen. Ich werde nicht näher darauf eingehen, wie es besser ist. Ich schlage sowieso vor, Sie sollten sich nur daran gewöhnen, Ausnahmen standardmäßig zu verwenden. Beachten Sie jedoch, dass die Verwendung von Ausnahmen einige heikle Probleme hat (zB RAII http://en.wikipedia.org/wiki/RAII), die letztendlich Ihren Code verbessern, aber Sie sollten darüber in einem Buch lesen (ich kann hier nicht beschreiben und fühle, dass ich dem gerecht werde Gegenstand). Ich denke, das Buch "Effective C++/Scott Meyer" beschäftigt sich damit sicherlich "Exceptional C++/Herb Sutter". Diese Bücher sind ein guter Anfang für jeden C++ Entwickler, wenn Sie sie noch nicht gelesen haben.

Verwandte Themen