Eigene exception



  • Hallo,

    ich versuche eine eigene Exception zu bauen. Also neben std::runtime_error möchte ich sowas machen ich weiß nur nich wie:

    try {
       foo();
    } catch (std::runtime_error& ex)
    {
    
    } catch (my_error& ex)
    {
    
    }
    

    hat jemand einen guten linke oder hinweise? Danke



  • Du musst einfach nur eine Klasse Anlegen, die du werfen willst. std::runtime_error ist auch nur eine gewöhnliche Klasse. Es geht sogar mit Integern:

    try{
       throw 5;
    } catch (int e) {
       cout<<e<<endl;
    }
    


  • Hier ein guter Link: http://magazin.c-plusplus.net/artikel/Exception-Handling

    Du kannst dir eine eigene Klasse schreiben. Prinzipiell kannst du in C++ alles werfen, auch int oder irgendwas. Aber eine Klasse ist meist besser geeignet.



  • class my_error : std::exception
    {
    // my_error ist eine stinknormlae Klasse, also alles rein was Klassen bracuhen vor allem nen guten Destruktor!
    };
    
    void foo() thor(my_error)
    {
    //
    }
    

    mehr brauchts nicht!



  • Paulchen schrieb:

    // my_error ist eine stinknormlae Klasse, also alles rein was Klassen bracuhen vor allem nen guten Destruktor!

    GRRRR meinte KONstruktor... Sry Weihnachten macht mich immer nervös 😛



  • Paulchen schrieb:

    void foo() thor(my_error)
    {
    //
    }
    

    Bist du ein Wikinger? :xmas2:



  • Danke euch. Es wird mir etwas klarer.

    Ich würde gerne so vorgehen - vorsicht es ist pseudocode:
    wäre das richtig?

    // MyException.h
    class MyException
    {
        public:
            MyException() { };
    };
    
    //main.cpp
    #include "MyException.h"
    
    void foo() 
    {
          if(something_happend)
               throw MyException("Hier ist ein fehler aufgetreten ");
    }
    
    int main( void )
    {
         try {
             foo();
        } catch (MyException() & ex)
         {
             std::cerr << ex.what() << std::endl;
         }
    }
    


  • Ja, wobei du von std::exception ableiten kannst, um Exceptions einheitlich zu behandeln. Dann hast du gleich die what() -Methode, und es geht nur noch darum, im Konstruktor die Basisklasse mit dem übergebenen String richtig zu initialisieren.

    Ausserdem müsste der catch -Block so aussehen:

    catch (MyException& ex)
    {
        // ...
    }
    


  • danke vielmals...

    und es geht nur noch darum, im Konstruktor die Basisklasse mit dem übergebenen String richtig zu initialisieren.

    ich überlege wie ich das noch realisieren kann...



  • gafabi schrieb:

    ich überlege wie ich das noch realisieren kann...

    Tipp: Konstruktor-Initialisierungsliste.



  • Wieso wirft man nicht einfach Integer?



  • Samyboy schrieb:

    Wieso wirft man nicht einfach Integer?

    Weil man dann nicht speziell nach Typen fangen kann. Man müßte immer fangen und je nach int-Wert handeln oder weiterwerfen.

    void foo(){
       try{
          for(...
       }
       catch(DivisionByZeroError& e){
          throw UserHatPechError("Matrix kann nicht invertiert werden");
       }
    }
    
    main(){
    nochmal:;
    try{
        foo();
    }
    catch(FileNotFoundError& e){
       cout<<"Nochmal!\n";
       goto nochmal;
    }
    catch(OurOfMemeoryError& e){
       cout<<"Mehr RAM kaufen und dann nochmal starten!\n";
       return 17;
    }
    catch(LogicError &e){
       cout<<"Programmierer ist doof\n";
       cout<<e.what()<<' '<<e.where()<<' '<<e.when()<<' '<<e.why()<<'\n';
       return 18;
    }
    catch(...){
       cout<<"unbekannter Fehler\n";
       return 18;
    }
    

    LogicError ist Basisklasse von ArrayOutOfBoundsError, ArgumentsNotValidError, StackIsEmtyError und so weiter, praktisch alles, was der Programmierer verbaseln kann, und was im Release-Code niemals fliegen darf.



  • scheiße ich komm net drauf..

    Tipp: Konstruktor-Initialisierungsliste.

    weitere tipps?



  • also so in etwas?

    // MyException.h
    class MyException : public std::runtime_error
    {
        public:
            MyException(std::runtime_error err) : std::runtime_error(err) { };
    };
    

    ?



  • Fast. 😉

    MyException(const std::string& err);
    


  • danke schonmal.

    ich fasse nochmal zusammen:
    Also so in etwas? 🙂

    #include "exception.h"
    // MyException.h
    class MyException : public std::exception
    {
        public:
            MyException(const std::string& err) : std::exception(err) { };
    };
    
    //main.cpp
    #include "MyException.h"
    
    void foo()
    {
          if(something_happend)
               throw MyException("Hier ist ein fehler aufgetreten ");
    }
    
    int main( void )
    {
         try {
             foo();
        } catch (MyException& ex)
         {
             std::cerr << ex.what() << std::endl;
         }
    }
    


  • gafabi schrieb:

    Also so in etwas? 🙂

    #include "exception.h"
    // MyException.h
    class MyException : public std::exception
    {
        public:
            MyException(const std::string& err) : std::exception(err) { };
    };
    

    Nicht ganz. std::exception implementiert selbst keine what()-Methode und vor allem keinen entsprechenden Konstruktor. Die what()-methode muss von abgeleiteten Klassen selber implementiert werden.
    http://cplusplus.com/reference/std/exception/exception/
    Es gibt allerdings eine Reihe weitere Exception-Klassen im Standard, die entsprechende Konstruktoren bereits haben und auch die waht()-Methode entsprechend implementieren:
    http://cplusplus.com/reference/std/stdexcept/
    Da wirds sicher eine Kategorie geben in die du deinen Fehler einordnen kannst, so dass du von der entsprechenden Exception aus <stdexcept> ableiten kannst.



  • jetzt komm ich in teufels küche....

    ich wollte sowas machen:

    #include <stdexcept>
    // MyException.h
    class MyException : public std::runtime_error
    {
        public:
            MyException(const std::string& err) : std::runtime_error(err) { };
    };
    
    //main.cpp
    #include "MyException.h"
    
    void foo()
    {
          if(something_happend)
               throw MyException("Hier ist ein fehler aufgetreten ");
    }
    
    int main( void )
    {
         try {
             foo();
        } catch (std::runtime_error& ex)
        {
             std::cerr << ex.what() << std::endl;
         }
          catch (MyException& ex)
         {
             std::cerr << ex.what() << std::endl;
         }
    }
    

    ich bekomme jetzt vom compiler folgende meldungen:

    ../src/main.cpp:236: Warnung: Ausnahme des Typs »Pe_Exception« wird gefangen werden
    ../src/main.cpp:210: Warnung:    von früherem Behandler für »std::runtime_error«
    

    Ich kann verstehen dass ich da evtl. blödsinn mache...meine absicht war folgende:
    Ich wollte eine reihe von runtime-fehlern in der main einfach über eine runtime_error exception fangen. Einen speziellen runtime_error will ich jetzt gesondert abfangen.



  • Dann fang MyException einfach vor der runtime_exception ab.



  • tatsächlich....nur verstehen tu ichs im moment noch nicht .....warum meckert er da. die reihenfolge ist doch egal oder nicht?


Anmelden zum Antworten