Was genau bringen exceptions?



  • Hey!

    Der code wird doch viel länger, wenn man exceptions verwendet...

    #ifndef INCLUDED_ERRORMESSAGE
    #define INCLUDED_ERRORMESSAGE
    
    #include <string>
    #include <windows.h>
    
    class ErrorMessage
    {
    	std::string errorMessage;
    	std::string errorId;
    public:
    	ErrorMessage(std::string, std::string);
    	~ErrorMessage();
    
    	std::string& getErrorMessage();
    	std::string& getErrorId();
    };
    
    #endif // INCLUDED_ERRORMESSAGE
    
    ...
    
    HWND hWnd = CreateWindow("Main", "Blubbor", WS_POPUP, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
    
    	try
    	{
    		if(!hWnd)
    			throw ErrorMessage("Could not create drawing window", "001");
    	}
    	catch(ErrorMessage& errorMessage)
    	{
    		MessageBox(NULL, errorMessage.getErrorMessage().c_str(), ("Error ID: " + errorMessage.getErrorId()).c_str(), MB_OK);
    		exit(0);
    	}
    
    ...
    

    Verstehe ich die exceptions überhaupt richtig? Also mache ich es richtig/effektiv?

    if(!hWnd)
    MessageBox(NULL, "....

    wär doch viel einfacher?

    MfG



  • naja exceptions machen das alles nur auf den ersten blick unübersichtlicher, aber die sind gut für das in objektorientierter Programmierung so großgeschiebenem Prinziep der Datenkapselung. Dann kann man seine Fehler behandeln, wo man will, oder die gleiche funktion zweimal aufrufen, und den Aufgefangenen Fehler aber unterschiedlich behandeln, sofern er geworfen wurde. Um deine Frage zu beantworten, ob du es effektiv machst, nein, aber das ist frn Anfang auch erst nicht so schlimm, setzt mal ein throw in eine Funktion ein, und den try-Block in die main, und behandle wie oben beschrieben mal bei der gleichen Funktion den Fehler anders.

    Sowas hilft einem Die Fehler in jeder ebene des Programms einzeln zu behandeln, man kann auch unterschiedliche fehler werfen, und mehrere ineinander Verschachtelte try-Blöcke erstellen, denn wenn bei ersten der Fehler nicht behandelt wurde, wird bei der nächst höheren ebene nach der Fehlerbehandlung gesucht.



  • Aha.

    Warum ist das nicht effektiv?
    Der try-Block steht in der main. In CreateWindow kann ich schlecht ein try stecken.

    "behandle wie oben beschrieben mal bei der gleichen Funktion den Fehler anders"

    Hä?

    MfG



  • naja, ein vorteil wäre, du brauchst dich nicht um rückgabecodes zu kümmern.
    machmal (manchmal auch oft) macht man das aus faultheit nicht. dann kämpft man mit "unsichtbaren" fehlern. mit exceptions lässt sich soetwas so ziemlich reduzieren.

    exceptions sind immer gleich. fehlercodes wird auf verschiedene weisen gemacht. manche geben im fehlerfall 0 zurück, andere negative zahlen oder positive zahlen.

    du kannst zwar in CreateWindow keinen throw reinstecken. aber du kannst CreateWidndow samt if und throw in eine andere funktion reinstecken.



  • ceplusplus schrieb:

    Hey!

    Der code wird doch viel länger, wenn man exceptions verwendet...

    Nein, er wird kürzer, und zwar deutlich. Und es fällt viel "if(!dings) dongs()" weg, was ich als "noise" Bezeichnen würde.
    Alles in allem eine gute Sache, bloss verstanden muss man es mal haben. Wenn kann man sich damit auch ganz prima selbst in den Fuss schiessen... aber das ist beim Programmieren und speziell in C++ ja nix neues.



  • In C++ werden exceptions doch nicht richtig unterstützt, wenn ich in Java ne exception werf, dann muss ich sie auch fangen, sonst gibts nen compileerror, wenns keine runtimeexception ist.



  • Und was ist der Unterschied ob ich in Java in main() alle Exceptions fange und dann einfach das Programm beende oder C++ das gleich implizit machen zu lassen?

    Java hat für meinen Geschmak zu viel Zwang. z.B. bekomme ich so etwas nicht kompiliert:

    public int abc()
    {
        int i = 5;
    
        //...
    
        if(i = 5)
        {
            return i;
        }
        else
        {
            return -i;
        }
    }
    

    In diesem beispiel trivial, hat mich aber schon ziemlich genervt, dass ich ein return an das Ende stellen musste, das garantiert nie aufgerufen wird.

    Wenn ich will, dass im Fehlerfall einfach das Programm beendet wird ist das in C++ durch einfaches nicht-fangen erreicht, in Java müsste ich schon wieder extra Code schreiben



  • Ford Perfect schrieb:

    In C++ werden exceptions doch nicht richtig unterstützt, wenn ich in Java ne exception werf, dann muss ich sie auch fangen, sonst gibts nen compileerror, wenns keine runtimeexception ist.

    Stimmt doch garnicht! Java-Exceptions die von RuntimeException abgeleitet sind, müssen nicht abgefangen werden! Manche Java-Exceptions wie OutOfMemory kann man sogar garnicht abfangen. Also, bitte keine Halbwahrheiten erzählen.



  • ceplusplus! Ein gaaanz besonderer Vorteil von Exceptions ggü. Returncodes ist, das man Exceptions auch viel später behandeln kann. D.h. du kannst Exceptions auch weiter werfen, wenn du mit dem Fehler nichts anfangen kannst. Das geht mit Returncodes garnicht. Bsp.:

    // LIBRARY CODE:
    void foo3() throw(std::invalid_argument)
    {
         throw std::invalid_argument("fehler in foo3!");
    }
    
    void foo2() throw(std::invalid_argument)
    {
         foo3(); // kein try, weiß nicht was ich sinnvoll darauf reagieren soll.
         // hier kommt Code, der was macht, wenn foo3 erfolgreich war...
         // ...
    }
    
    // CLIENT CODE:
    void foo1()
    {
         try {
            foo2();
         }
         catch(std::invalid_argument &e) {
            std::cout << e.what();
         }
    }
    

    So, in foo2() weiß ich nicht, wie ich auf den foo3()-Fehler reagieren soll. Das ist z.B. bei Bibliotheken sehr oft der Fall, das sie dem Bibliotheks-Benutzer über Fehler entscheiden lassen wollen. (in dem Fall ist foo1 der User-Code)

    Natürlich könnte foo2 einen Errorcode von foo3 zurück geben. Aber was ist, wenn foo2 drei andere Funktionen aufruft, die auch Fehler zurück geben könnten? Und die Errorcodes sich sogar überschneiden aber unterschiedliche Bedeutungen haben??? Oh backe! Wie soll die foo1 auseinanderhalten? 1 ist nunmal gleich 1. Obwohl die Einsen von zwei verschiedenen Funktionen kommen können, die innerhalb von foo2 aufgerufen wurden??? Mit Exceptions passiert das nicht, weil Exceptions meistens typisiert sind.

    Wennd du mit Errorcodes arbeitest, muß jede Funktion genau diesen Errorcode-Return anbieten und mitschleppen. Auch könnte jede Funktion die ihn mitschleppt zwischenzeitig illegalerweise verändern und somit den Programmfluss negativ beeinflussen.

    Bei Exceptions muß niemand sowas wie Errorcodes beachten. Die Exception schlägt einfach zurück und du kannst diese als Library-User auffangen und nach DEINEM pers. Ermessen behandeln und somit sinnvoll reagieren.

    Exceptions sind einfach auch eine mächtigere Programmflusssteuerung, die nicht nur eine Info X liefert (wie es Errorreturncodes nur leisten können).



  • ceplusplus schrieb:

    Hey!
    Der code wird doch viel länger, wenn man exceptions verwendet...

    nö, er wird viel kürzer!

    HWND myCreateWindow(
    HWND CreateWindow(LPCTSTR a,LPCTSTR b,DWORD c,int d,int e,int f,int g,HWND h,HMENU i,HINSTANCE j,LPVOID k)
    {
       HWND hWnd = CreateWindow(a,b,c,d,e,f,g,h,i,j,k);
       if(!hWnd)
          throw ErrorMessage("Could not create drawing window", "001");
       return hWnd;
    }
    

    und ab heute verwendest du nur noch myCreateWindow. und alle anderen winapi-funktionen verpackst du auch mit einem exeptionwerfenden wrapper.

    Verstehe ich die exceptions überhaupt richtig?

    nö. wer in c++ exit(0) aufruft, beschwört dicke probleme herauf. fang lieber in der main() die exceptions.



  • ceplusplus schrieb:

    Hey!

    Der code wird doch viel länger, wenn man exceptions verwendet...

    #ifndef INCLUDED_ERRORMESSAGE
    #define INCLUDED_ERRORMESSAGE
    
    #include <string>
    #include <windows.h>
    
    class ErrorMessage
    {
    	std::string errorMessage;
    	std::string errorId;
    public:
    	ErrorMessage(std::string, std::string);
    	~ErrorMessage();
    
    	std::string& getErrorMessage();
    	std::string& getErrorId();
    };
    
    #endif // INCLUDED_ERRORMESSAGE
    
    ...
    
    HWND hWnd = CreateWindow("Main", "Blubbor", WS_POPUP, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
    
    	try
    	{
    		if(!hWnd)
    			throw ErrorMessage("Could not create drawing window", "001");
    	}
    	catch(ErrorMessage& errorMessage)
    	{
    		MessageBox(NULL, errorMessage.getErrorMessage().c_str(), ("Error ID: " + errorMessage.getErrorId()).c_str(), MB_OK);
    		exit(0);
    	}
    
    ...
    

    Verstehe ich die exceptions überhaupt richtig? Also mache ich es richtig/effektiv?

    if(!hWnd)
    MessageBox(NULL, "....

    wär doch viel einfacher?

    MfG

    Naja, da hast Du ja auch eine exception verwendet, wo es wenig sinnvoll ist.
    Stell die Frage nochmal mit:

    class A {}
    bool f1(A& a);
    bool f2(A& a);
    bool f3(A& a);
    bool f4(A& a);
    bool f5(A& a);
    bool f6(A& a);
    bool f7(A& a);
    bool f8(A& a);
    bool f9(A& a);
    bool f10(A& a);
    
    int main() {
       A a;
       try {
    	f1(A& a);
    	f2(A& a);
    	f3(A& a);
    	f4(A& a);
    	f5(A& a);
    	f6(A& a);
    	f7(A& a);
    	f8(A& a);
    	f9(A& a);
    	f10(A& a);
       }
       catch(...) {
          // do something
       }
       // Hier soll es weitergehen mit einem a, das nur erfolgreiche f_() durchlaufen hat !
       return 0;
    }
    

    Oder wie Du Fehlersituationen in Konstruktoren abhandeln willst, oder wie Du als Programmierer einer Funktion sicherstellen willst, dass Dein Aufrufer auch sicher die Fehlersituation bemerkt, oder ....

    Gruß,

    Simon2.



  • darthdespotism schrieb:

    Und was ist der Unterschied ob ich in Java in main() alle Exceptions fange und dann einfach das Programm beende oder C++ das gleich implizit machen zu lassen?

    Es ist auch nicht der Sinn von Exceptions, alles in main zu fangen. Wenn man die Exception an der richtigen stelle fängt, dann kann man auch ne sinnvolle Fehlerbehandlung machen und nicht nur im catch(...) "sagen irgendwas war falsch, tschüs".

    Java hat für meinen Geschmak zu viel Zwang. z.B. bekomme ich so etwas nicht kompiliert:

    public int abc()
    {
        int i = 5;
    
        //...
    
        if(i = 5)
        {
            return i;
        }
        else
        {
            return -i;
        }
    }
    

    Natürlich, weil eine zuweisung keinen boolschen wert liefert.

    Artchi schrieb:

    Ford Perfect schrieb:

    In C++ werden exceptions doch nicht richtig unterstützt, wenn ich in Java ne exception werf, dann muss ich sie auch fangen, sonst gibts nen compileerror, wenns keine runtimeexception ist.

    Stimmt doch garnicht! Java-Exceptions die von RuntimeException abgeleitet sind, müssen nicht abgefangen werden!

    Lern lesen!

    Manche Java-Exceptions wie OutOfMemory kann man sogar garnicht abfangen. Also, bitte keine Halbwahrheiten erzählen.

    Falsch! Es heist ja schon OutOfMemoryError und nen Error kann man auch fangen (auch wenns selten sinnvoll ist), schau dir mal die vererbungshierarchie an.



  • Ein Tipp der mir geholfen hat.

    Wann immer man ein Sprachkonstrukt nicht versteht und es unsinnig erscheint sollte man nciht damit anfangen den Fehler bei dem Sprachkonstrukt (in dem fall exceptions) zu suchen sondern erstmal bei sich selber. In 90% der Fälle liegt es lediglich an der eigenen Unfähigkeit etwas Neues zu begreifen, wogegen man aber etwas machen kann.

    Das klappt aber nur wenn man auch bereit ist zu akzeptieren das es an einem selber liegt, wie in diesem Fall mehr als deutlich.



  • ich les die erste seite und freu mich zu antworten, aber for perfect hat schon alles gesagt was ich sagen wollte 😞 👍



  • Ganz unabhängig vom Inhalt (zu dem ich nichts zu sagen habe)

    Ford Perfect schrieb:

    ...
    Lern lesen!
    ...

    🙄 🙄 🙄
    MUSS man wirklich derart unfreundlich werden ? Stell' Dir einfach mal vor, der Knabe säße Dir gegenüber .... hättest Du ihm das auch so an den Kopf geknallt ?
    Solch ein Verhalten macht das Forumsklima kaputt und hilft keinem weiter ....

    Gruß,

    Simon2.



  • @Simon2:

    Äh. Und zu antworten obwohl man nichtmal vollständig gelesen und/oder verstanden hat was jmd. anderer geschrieben hat ist natürlich garnicht unfreundlich sondern vollkommen OK oder wie?

    Klar *kann* man auf die "Unfreundlichkeit" eines anderen freundlich reagieren, kann ich nix schlechtes daran finden, aber erwarten tu' ich das nicht.



  • hustbaer! Sorry, aber das ist ja wohl nicht korrekt, das ein nicht registrierter anonymer Assi mir sagt, ich das ich lesen lernen soll? 😡 Die Unregs sollen mal schön den Ball flach halten. Ich lasse mich lieber von einem gestandenen Forenmitglied anmachen, als von jemanden, der so feige ist, nur zu posten, wenn er nicht seine Person kenntlich macht. Aber ich habe eh nicht auf seine Reaktion reagiert, weil er mir am Arsch vorbei geht. Ganz davon abgesehen, das ich sowieso Recht habe. :p



  • Artchi schrieb:

    hustbaer! Sorry, aber das ist ja wohl nicht korrekt, das ein nicht registrierter anonymer Assi mir sagt, ich das ich lesen lernen soll? 😡 Die Unregs sollen mal schön den Ball flach halten.

    Dass Du denjenigen dann als Assi bezeichnest ist hingegen natürlich völlig in Ordnung. 👍



  • Ja und? Habe ich doch schon gesagt: unbekannt, eine Nummer, mehr nicht. Kenne nicht mal seinen Namen. Hätte auch ein Bot sein können. Was erwartet man denn? Das ich mich bei dem anonymen unbekannten feigen Unreg entschuldige? 😮 Wir reden hier nicht über Personen die mir/uns bekannt sind. (die dann "menschlich" sind und ich entsprechend respektvoller behandel) Aber ist eh offtopic...



  • Es gibt überhaupt keinen Grund, warum wir vier (Artchi, hustbaer und Jester - alles "renommierte Forumsteilnehmer", die bislang Fachwissen und soziale Kompetenz bewiesen haben) uns hier gegenseitig an die Gurgel gehen sollten ... aber
    genau diese Rumpamperei ist das Ergebnis davon, dass Leute (und es stimmt: Fast immer Leute, die sich hinter "unregistriert" verstecken) hier den "Umgangston versauen".
    Und ich kann mich nicht des Eindrucks erwehren, dass sich da jetzt jemand die Hände reibt und diebisch freut, dass wir ihm mit unserer Diskussion mehr Aufmerksamkeit schenken, als er verdient hat.

    Gruß,

    Simon2.

    P.S.: Ich habe mich zwar nicht inhaltlich an dem "Java-Subthema" beteiligt, aber durchaus mitgelesen und nichts in Artchies Verhalten gefunden, was diese "Antwort" gerechtfertigt hätte - außerdem ist das genau leider die Strategie, die ich hier schon öfter von Unregistrierten erlebt habe: Ist jemanden in einem speziellen Punkt anderer Meinung, wird ihm sofort ein IQ von Brot zugeschrieben.
    Ich habe eine Fußnote im Standard übersehen => Ich bin unfähig zu lesen;
    ich habe ein Konstrukt mißverstanden => Ich bin offensichtlich ein Totalversager;
    ich setze lieber Technik A statt Technik B ein => Ich würde bei der Kinderkrippenaufnahmeprüfung für Schimpansen durchfallen. .... 🙄
    das nervt und macht das Forum kaputt - und ich glaube, das soll es auch. Und weil ich das nicht möchte, sage ich etwas dagegen => Ja, ich finde das OK.


Log in to reply