Datum erhöhen, die vierte Version



  • Das habe ich schon mal gemacht und es gab einen Programm absturz.



  • Weil deine Abfrage im Konstruktor falsch ist, und invalid getrowed wird.

    max>x
    

    -> immer throw



  • Genau das war das Problem wieder ein schreib Fehler. OK das Programm lauft aber jetzt brauche ich eure Hilfe was könnte man in class Invalid schreiben wenn der Wert von Year nicht korrekt ist?



  • Glueck verschenken, selber denken ....



  • Um class Invalid wird später etwas gemacht, aber wieso wir ein ungültiges Wert ausgegeben obwohl das im Date Konstruktor eine Prüfung geschrieben wurde??

    Date::Date(Year y, Month m, int d):y(y), m(m), d(d)
    {
    	if(d<1 || d>31) { d = 0; }
    }
    


  • Die Lösung war:

    Date::Date(Year y, Month m, int d):y(y), m(m), d(d)
    {
        if(d<1 || d>31) { this->d = 0; }
    }
    


  • Weil du lokal d deklariert hast, und somit den Klassenmember verdeckst.



  • Ich habe bis jetzt noch nie mit Memberklassen gearbeitet, wenn ich das schreibe bekomme ich Compiler Fehler.

    Year::Invalid()
    {
    	cout << 0;
    }
    

    Übrigens muss man bei Invalid nichts machen, hab es nochmal die Aufgabe gelesen, Invalid muss einen Lauftzeitfehler ausgeben.



  • Jetzt eine andere Frage warum kann man nicht folgendes schreiben:

    ostream& operator<<(ostream& os, const Date& d)
    

    Wenn ich das schreibe bekomme ich einen Compiler Fehler, hat das mit dem this-> zu tun oder das man eine Parametervariable d und eine Membervariable d gibt?



  • Wenn du das innerhalb der Klasse machen willst, dann muss es ein friend operator sein.



  • Ich meine ich kann Date& d nicht als const setzen. Der Compiler sagt Date::day :this-Zeiger kann nicht von const Date in Date& konvertiert werden.



  • Zeig doch mal was du hast.



  • class Year{
    	static const int min = 1800;
    	static const int max = 2200;
    public:
    	class Invalid {};
    	Year(int x):y(x) {if(x<min || max<x) throw Invalid();} 
    	int year() { return y;}
    private:
    	int y;
    };
    
    class Date{
    public:
    	enum Month{
    		jan=1,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec
    	};
    	Date(Year y, Month m, int d);  // checking for valid date and does the initialization
    	int day() { return d; }        
    	void add_day(int n);          // increase Day with n value
    private:
    	Year y;
    	Month m;
    	int d;  // Day
    };
    
    Date::Date(Year y, Month m, int d):y(y), m(m), d(d)
    {
    	if(d<1 || d>31) { this->d = 0; }
    }	  
    
    void Date::add_day(int n)
    {
    	if(d + n >= 32) { d = 0;} 
    	else {d = d + n;}
    }
    
    ostream& operator<<(ostream& os, Date& d) // hier statt Date& d könnte
    {                                         // const Date& d stechen 
        return os << '"' << d.day() << '"' ; 
    } 
    
    void f()
    {
    	Date today(Year (1978),Date::jun,25);
    	cout << today << endl;
    
    	Date tomorrow = today;
    	tomorrow.add_day(1);
    	cout << tomorrow << endl;
    
    	Date non = today;
    	non.add_day(12);
    	cout << non << endl;
    
    	Date non2(Year (2000),Date::mar,-56);
    	cout << non2 << endl;
    }
    
    int main()
    try{
        f();
    
        keep_window_open();
        return 0;
    }
    catch (runtime_error e) {    
        cout << e.what() << '\n'; 
        keep_window_open("~");    
    } 
    catch (...) {    
        cout << "exiting\n"; 
        keep_window_open("~");    
    }
    


  • Du Funktion day muss natürlich auch const sein, wenn du über eine const& darauf zureifen willst, wäre ja blöd, wenn diese Funktion etwas verändern würde, obwohl es eigentlich const sein sein muss.


  • Mod

    Dies ist ein Fehler in der const-Correctness:

    Dein operator<< benutzt d.day(). Du willst, dass d konstant sein darf, daher darf d.day() das d nicht verändern. Dies kann der Compiler an der Stelle aber nicht sicher prüfen ob dies tatsächlich der Fall ist. Um ihm mitzuteilen, dass d.day() das d nicht verändert, musst du weiter oben

    int day() const { return d; }
    

    schreiben.

    Milde Warnung: const-Correctness ist ansteckend. Wenn du erst einmal anfängst an einer Stelle const zu setzen dann wirst du (wie hier) nach und nach gezwungen an vielen anderen Stellen const zu setzen. Lass dich aber davon nicht abschrecken. Const-Correctness hilft dir dabei, korrekte Programme zu schreiben, weil es (wie das Typensystem) dem Compiler ermöglicht, gewisse Fehler in der Programmlogik zu erkennen.



  • Und wieder was gelernt, dank auch ist jetzt alles klar und man kann hier im Forum viel neues lernen. Danke nochmals an alle für die Hilfe.


Anmelden zum Antworten