exception what() mit parameter



  • hallo leute,
    ich habe eine exception klasse erstellt, die std::exception erbt.
    kurze frage, kennt jemand eine möglichkeit, die what() methode so zu überladen das ich ihr parameter übereben kann?

    class ex : public std::exception {
      public:
    
      explicit ex(const std::string & msg = "" )
        : mMsg(msg) {}
    
      virtual ~ex() throw() {};
    
      virtual const char* what(bool t) const throw() {
        if(t)
          return mMsg.c_str();
        else
          return "ahhhhhhhhhh";
      }
    
      private:
    
      std::string mMsg;
    };
    
    void main() {
      try {
        throw(ex());
      }
      catch(std::exception &e) {
        std::cout << e.what() << std::endl;
      }
    }
    

    was für mich wichtig währe, dass ich in dem catch eine std::exception ist.
    sobald ich den catch mit ex mache gehts natürlich. oder wenn ich den parameter in der klasse weglasse, gehts natürlich auch. casten hat nicht funktioniert.
    bin für alle eingebungen dankbar. 🙂

    gruss pete



  • std::string in einer exception klasse is doof. wenn der speicher ausgeht kann da beim kopieren der exception ein bad_alloc fliegen, und dann fliegt dir dein programm um die ohren.
    besser std::shared_ptr<std::string> .

    was deine frage angeht: du kannst virtuelle funktionen natürlich nicht mit einer anderen signatur überschreiben, wie soll das gehen? woher sollen die parameter kommen?

    was du aber natürlich machen kannst, ist eine zusätzliche what(bool) methode, und die originale what() methode so überschreiben dass die what(bool) aufgerufen wird.

    also

    class ex : public std::exception {
      public:
    
      explicit ex(char const* msg = "" ) // wozu std::string als parameter? und wenn schon,
                                         // dann bitte by-value, damit gemoved werden kann
        : mMsg(std::make_shared<std::string>(msg ? msg : "")) {}
    
      virtual ~ex() throw() {};
    
      virtual const char* what() const throw() {
        return what(true);
      }
    
      virtual const char* what(bool t) const throw() { // muss nicht unbedingt virtual sein, darf aber gerne
        if(t)
          return mMsg->c_str();
        else
          return "ahhhhhhhhhh";
      }
    
      private:
    
      std::shared_ptr<std::string> mMsg;
    };
    

    ps: überladen und überschreiben ist was ganz anderes. dein code tut überladen, was du suchst ist aber überschreiben.



  • pi88el schrieb:

    kurze frage, kennt jemand eine möglichkeit, die what() methode so zu überladen das ich ihr parameter übereben kann?

    Genau das hast du doch getan. Es ist eine neue virtuelle Funktion what , die einen bool als Parameter nimmt.

    pi88el schrieb:

    [...]
    was für mich wichtig währe, dass ich in dem catch eine std::exception ist.
    sobald ich den catch mit ex mache gehts natürlich. oder wenn ich den parameter in der klasse weglasse, gehts natürlich auch. casten hat nicht funktioniert.
    bin für alle eingebungen dankbar. 🙂

    Du hast vergessen zu erklären, was Du hier mit "geht" und "nicht funktioniert" meinst. Ich sehe auf Anhieb kein Problem. Allerdings frage ich mich, was das mit der neuen what -Funktion da soll. Wenn ich raten müsste, würde ich sagen, du erwartest irgendwie, dass du auf e deine neue virtuelle Funktion aufrufen kannst. Aber e ist nunmal "nur" eine std::exception, und std::exception hat keine solche Funktion. Wenn du diese Funktion aufrufen willst, dann ändere std::exception &e in ex &e um oder lass es sein und verwende eine andere dynamische Sprache. In C++ will der Compiler schon während der Übersetzung sicher gehen können, dass es eine solche Funktion überhaupt gibt. Eine Referenz auf ein Objekt, was vom Typ std::exception ist oder davon ableitet, muss ein solches what(bool) gar nicht haben. Also kannst du es auch nicht aufrufen.

    Alternativ auch so:

    } catch (std::exception &e) {
      cout << "Ich habe eine std::exception gefangen!\n";
      ex* p = dynamic_cast<ex*>(&e);
      if (p) {
        cout << "Es ist sogar eine ex! " << p->what(true) << endl;
      } else {
        cout << "Es ist nur keine ex!\n";
      }
    }
    

    Allerdings sehe ich nicht, was das gegenüber

    } catch (ex &e) {
      ...
    } catch (std::exception &e) {
      ...
    }
    

    bringen soll.



  • danke für die infos, freunde.

    habe mich für einen mix aus beidem entschieden.

    Allerdings sehe ich nicht, was das gegenüber

    } catch (ex &e) {
    ...
    } catch (std::exception &e) {
    ...
    } 	
    C/C++ Code:
    } catch (ex &e) {
      ...
    } catch (std::exception &e) {
      ...
    }
    

    bringen soll.

    war nur so ne idee. in dem catch sollen eventuel weitere funktionen das exception verarbeiten, die ich dann nicht doppelt haben will.

    vielen dank und grüsse
    pete



  • Warum immer so kompliziert?

    struct my_exception : std::runtime_error // /std::logic_error/...
    {
        my_exception(std::string const& what)
            : runtime_error(what)
        {}
    };
    

Anmelden zum Antworten