Exception



  • Hi ich hab mal ne simple grundlegende Frage zu exceptions.

    try{
    .....throw(...);
    }
    catch(...){
    ...}
    

    So stehts in jedem Buch das ich gelsen hab und in jedem Tutorial.
    Nun die Frage. Das catch kommt immer direkt hinter dem try block. Ist das so ueblich? Ich fänd es viel logischer wenn man einer Sammelstelle hätte und dort alles einfängt. Jedoch sind die Beispiele in sämtlichen tutorials und Buechern so kurz, dass ich nicht rausfinden konnte ob man immer das catch dahinter packt oder nur an ein oder 2 Stellen im Kot catch verwendet. Denn wenn man catch immer dahinter packt kann man meiner Meinung es auch ganz sein lassen und den Fehler irgendwie per std::cout ausgeben.

    MFG
    chew



  • Hi,

    mit "try" gibst Du halt an, dass Du diesen Block "auf exceptions überwachen willst". Eigentlich wird anders ein Schuh draus: Wo immer Du ein "catch" schreiben willst, mußt Du diesem sagen, ab wo es "auf exceptions lauschen" soll.
    Vielleicht ist Dein Mißverständnis, dass man nur dort "throw-en" könnte, wo man in der vorherigen Zeile (oder in derselben Funktion, selbem Modul, ...) ein "try" hat. Dem ist nicht so.
    throw kannst Du überall machen ... catch aber nur nach einem vorhergehenden try.

    "Sammelstelle" ist damit ganz einfach implementiert:

    void alleMeineAusnahmen(myException const & e) {
        // ... mach was mit meiner exception
    }
    
    int main(void) {
        try {
            // arbeite; rufe Funktionen auf, die Funktionen aufrufen, die ... 
            // die exeptions werfen könnten; trys/catches braucht's dazwischen nicht.
        }
        catch(myException& e) {
            alleMeineAusnahmen(e);
        }
        catch(...) { // "..." ist hier sytaktisch w/richtig
            std::cout << "irgend eine andere exception gefangen
            throw;
        }
        return 0;
    }
    

    In meinem Beispiel gehe ich davon aus, dass Du eine eigene exception-Klasse ("myException") definierst (ruhig von std::exception abgeleitet), die Du entweder direkt instantiierst oder von der Du wiederum speziellere exceptions ableitest. Geht natürlich auch mit std::exception, aber da dessen Interface sehr schmal ist, bietet die sich nicht unbedingt zur "Sammelbehandlung" an (außer "Textausgeben" kann die nicht viel - unr dafür braucht's keinen "Sammler").

    Ich hoffe, es war verständlich.

    Gruß,

    Simon2,



  • chewbo! Das throw im try ist als Beispiel unglücklich. Da wo throw ist, muß ich noch kein try machen. Kann ich aber. Ich kann das try auch viel später einbauen.

    void foo1()
    {
       throw std::exception("was in foo1 falsch gelaufen.");
    }
    
    void foo2()
    {
      std::cout << "foo2 anfang \n";
      foo1();
      std::cout << "foo2 zuende \n";
    }
    
    void foo3()
    {
      std::cout << "foo3 anfang \n";
      try {
         foo2();
      } catch(std::exception &e) {
        std::cout << e.what() << std::endl;
      }
      std::cout << "foo3 zuende \n";
    }
    

    Der Clou an der Sache ist, das ich try ganz woanders eingebaut habe, obwohl throw in foo1 geworfen wird. D.h. ich kann viel später auf eine Exception reagieren. Ich muß das nicht in foo1 machen (was deinem Beispiel entsprechen würde) und auch nicht in foo2. Ich kanns auch in foo3 machen, wenn es mir reicht, das ich es erst dort abfange.

    In meinem Bsp. würde z.B. das auf dem Biildschirm ausgegeben werden:

    foo3 anfang
    foo2 anfang
    was in foo1 falsch gelaufen.
    foo3 zuende
    

    "foo2 zuende" würde nicht ausgegen werden, weil in foo1 der Fehler passierte, und ich habe in foo3 erst darauf reagiert. Cool, oder? 🙂

    Ansonst schau dir das hier mal an:
    http://www.kharchi.de/cppratgeber3.htm


Anmelden zum Antworten