try catch statements



  • hi leute!
    kann mir nochmal da try catch besser erklären? ich will da bei den methoden einzahlen und abheben try catch statements verwenden!! ich hatte vorher bool...wenn ein negativer betrag abgehoben werden soll dann gib bool false zurück...wie kann ich das am besten mit try catch machen? es soll am besten dann noch ein fehler ausgegeben werden, "kein negativer abhebbar" oder so!!

    ein freund hat mir hier geholfen:

    class no_money { };
      class bad_amount {
      private:
        float _m_amount;
      public:
        bad_amount(float);
        float get_amount() const;
      };
    

    aber irgendwie weiß ich nicht was das ganze da soll? no_money und bad_amount?? hmm...

    cu!!!

    das gesamte prog:

    klasse: konto
    ----------------------------------
    
    #ifndef INCLUDED_KONTO_HH
    #define INCLUDED_KONTO_HH
    
    #include <ostream>
    #include <string>
    using namespace std;
    
    class bank;
    
    class konto {
    private:
      std::string   _m_inhaber;
      unsigned long _m_kontonummer;
      float         _m_kontostand;
    
    public:
      class no_money { };
      class bad_amount {
      private:
        float _m_amount;
      public:
        bad_amount(float);
        float get_amount() const;
      };
    
      konto(const std::string& = "", unsigned long = 0, float = 0.0f);
    
      const std::string &get_inhaber    () const;
      unsigned long      get_kontonummer() const;
      float              get_kontostand () const;
    
      void einzahlen(float amount);
      void abheben  (float amount);
    
      friend class bank;
    };
    
    std::ostream &operator<<(std::ostream&, const konto&);
    
    #endif
    
    klasse: bank
    ---------------------------------
    
    #ifndef INCLUDED_BANK_HH
    #define INCLUDED_BANK_HH
    
    #include <map>
    #include <string>
    using namespace std;
    
    #include "konto.h"
    
    class bank {
    public:
      typedef std::map<unsigned long, konto> container_type;
      typedef container_type::key_type       key_type;
      typedef konto mapped_type;
      typedef container_type::value_type     value_type;
    
      typedef container_type::iterator       iterator;
    
    private:
      container_type _m_konten;
      unsigned long  _m_blz;
    
    public:
      bank(unsigned long);
    
      void generate_konto(const std::string &inhaber, float kstand);
      void geld_Einzahlen(unsigned long kontonummer, float betrag);
    
      unsigned long get_blz() const;
    
      mapped_type &operator[](key_type);
      iterator    find       (key_type);
    
      iterator    begin();
      iterator    end  ();
    
      //...sonstige Funktionen
    };
    
    #endif
    
    konto.cpp
    -------------------------------------
    
    #include <ostream>
    #include <string>
    using namespace std;
    
    #include "konto.h"
    
    konto::bad_amount::bad_amount(float amt) : _m_amount(amt) { }
    
    float konto::bad_amount::get_amount() const { return _m_amount; }
    
    konto::konto(const std::string &inhaber,
    	     unsigned long      knummer,
    	     float              kstand)
      : _m_inhaber    (inhaber),
        _m_kontonummer(knummer),
        _m_kontostand (kstand) {}
    
    const std::string &konto::get_inhaber    () const { return _m_inhaber    ; }
    unsigned long      konto::get_kontonummer() const { return _m_kontonummer; }
    float              konto::get_kontostand () const { return _m_kontostand ; }
    
    void konto::einzahlen(float amount) {
      if(amount < 0)
        throw bad_amount(amount);
      _m_kontostand += amount;
    }
    
    void konto::abheben(float amount) {
      if(amount < 0)
        throw bad_amount(amount);
      if(amount > _m_kontostand)
        throw no_money();
      _m_kontostand -= amount;
    }
    
    std::ostream &operator<<(std::ostream &os, const konto &k) {
      return os << "--------------------------------"       << std::endl
    	    << "Kontoinhaber:  " << k.get_inhaber    () << std::endl
    	    << "Kontonummer:   " << k.get_kontonummer() << std::endl
    	    << "Kontostand:    " << k.get_kontostand () << std::endl
    	    << "--------------------------------";
    }
    
    bank.cpp
    -----------------------------------------
    
    #include <iostream>
    #include "bank.h"
    
    bank::bank(unsigned long blz) : _m_blz(blz) {}
    
    unsigned long      bank::get_blz() const { return _m_blz; }
    
    /*bank::mapped_type &bank::operator[](bank::key_type k) { return _m_konten[k]     ; }*/
    bank::iterator     bank::find      (bank::key_type k) { return _m_konten.find(k); }
    
    bank::iterator     bank::begin() { return _m_konten.begin(); }
    bank::iterator     bank::end  () { return _m_konten.end  (); }
    
    void bank::generate_konto(const std::string &inhaber, float kstand)
    {
    	unsigned long kontonummer = rand();
    
    	konto k1(inhaber.c_str(), kontonummer, kstand);
    
    	// Konto hinzufuegen in die map
    	_m_konten[kontonummer] = k1;
    }
    
    void bank::geld_Einzahlen(unsigned long kontonummer, float betrag)
    {
        container_type::iterator toFind;
    
    	toFind = _m_konten.find(kontonummer);
    
    	if(toFind != _m_konten.end())
    	{
    
    		// damit findet man also den Iterator zu dem Konto, von dem das Geld abgehoben werden soll, den Code übernimmt man dann für die Klasse, zu der geschickt werden soll und dann hat man im Endeffekt zwei Iteratoren 
    	    (toFind->second).einzahlen(betrag);
    	}
    
    	/*for(toFind = _m_konten.begin(); toFind != _m_konten.end(); ++toFind) 
    	{
    		if((toFind->second).get_kontonummer() == kontonummer) 
    			break;
    	}*/
    
    	 //container_type::iterator konto_von = toFind;
    
    	//(konto_von->second).einzahlen(betrag);
    } 
    
    main.cpp
    ---------------------------------------
    
    #include <iostream>
    #include <sstream>
    #include <string>
    using namespace std;
    
    #include "bank.h"
    #include "konto.h"
    
    int main() {
       bank commerzbank(25040066);
    
       commerzbank.generate_konto("Max Meier", 100.00f);
       commerzbank.generate_konto("Hans Mustermann", 100.00f);
       commerzbank.generate_konto("Erwin Blubb", 100.00f);
    
      ostringstream os;
    
      // 10 Konten erstellen
      for(int j = 0; j < 10; ++j) 
      { 
    	  os.str("");
    	  os << "Name" << j; 
    	  commerzbank.generate_konto(os.str(), 100.00f);
      }
    
      // Betragauf bestimmte kontonummer einzahlen
      commerzbank.geld_Einzahlen(41, 50);
    
      // alle konten ausgeben auf bildschirm
      for(bank::iterator i = commerzbank.begin(); i != commerzbank.end(); ++i)
      {
    	  std::cout << i->second << std::endl;
      }
    
      return 0;
    }
    


  • Ich hoffe, das hilft dir weiter:
    http://www.hlrs.de/people/mueller/tutorials/script/scriptse34.html

    Zu deiner Frage:

    void konto::abheben(float amount) {
      if(amount < 0)
        throw bad_amount(amount); // ***
      if(amount > m_kontostand)
        throw no_money();
      m_kontostand -= amount;
    }
    
     try
    {
    // viel Code...
    meinKonto->abheben(-50);
    // viel Code...
    }
    catch(bad_amount& e)
    {
    // ***
    cerr << "Fehler: Sie dürfen nicht " << e.amount() << " EUR abheben!\n";
    }
    catch(no_money)
    {
    cerr << "Fehler: Sie haben zu wenig Geld!\n";
    }
    

    Exceptions sind im Prinzip ein funktionsübergreifendes return: Beim throw hört die Programmausführung auf und wird im entsprechenden Catch-Block fortgesetzt. Die lokalen Variablen werden allerdings ordentlich aufgeräumt, so dass dort keine Speicherlecks o.Ä. entstehen. Je nach Datentyp der Exception wird der Code im entsprechenden catch-Block ausgeführt. Die Tatsache, dass sich Exceptions an Datentypen orientieren, hat auch den Vorteil, dass einem nicht früher oder später die Rückgabewerte ausgehen, man den Fehlern schöne Namen geben kann und noch einige Informationen über den Fehler in die Klasse packen kann 😉



  • hi...aso geht das!!!
    kannst du mir sagn warum man da no die klassen no_money und bad_amount braucht??
    das leuchtet mir nit ganz ein, kann ich nicht einfach 2 methoden definieren?

    cu

    class no_money { }; 
      class bad_amount { 
      private: 
        float _m_amount; 
      public: 
        bad_amount(float); 
        float get_amount() const; 
      };
    


  • Du brauchst die Klassen, damit du einen eindeutigen Datentyp, d.h. einen eindeutigen Fehlercode hast.
    Nach Typ wird unterschieden, welcher Fehler aufgetreten ist, und je nach dem, welcher Wert "gethrowt" wird, kannst du genaueres über den Fehler erfahren.



  • ok gut...was würdest du an meinem prog no umbauen? try catch passt soweit oder soll ich noch was erweitern??
    bitte um comments!

    cu



  • hmmm??



  • Ich sehe in deinem Code kein try/catch. Was genau willst du wissen?
    Wenigstens um den kompletten Code in main() würde ich ein try/catch setzen und alle Exceptions fangen, damit man eine anständige Fehlermeldung ausgeben kann.


Anmelden zum Antworten