Datum erhöhen, die zweite Version



  • Danke für den Hinweis, es ist ein dummer schreib Fehler. Es werden zwei werte ausgeben soweit so gut, aber nur nicht die richtigen und das werde ich jetzt beheben. Das mit dem this ist gut gemeint nur das wird in einem späteren Kapitel erklärt, und jetzt weiß ich nicht was this macht.

    Habe this geschrieben und die werte sind korrekt.

    OK werte sind korrekt jetzt geht es ans add_day.



  • winux schrieb:

    Das mit dem this ist gut gemeint nur das wird in einem späteren Kapitel erklärt, und jetzt weiß ich nicht was this macht.

    this sagt, dass die Member der Klasse und nicht die Parameter gemeint sind. Du könntest stattdessen auch die Parameter yy, mm, dd nennen oder die Member m_y oder was auch immer, so dass du nicht zwei mal den gleichen Namen für verschiedenen Dinge verwendest.

    m_ als Präfix für Membervariablen ist nicht unüblich, es gibt aber auch viele Meinungen dagegen.



  • manni66 schrieb:

    winux schrieb:

    Das mit dem this ist gut gemeint nur das wird in einem späteren Kapitel erklärt, und jetzt weiß ich nicht was this macht.

    this sagt, dass die Member der Klasse und nicht die Parameter gemeint sind. Du könntest stattdessen auch die Parameter yy, mm, dd nennen oder die Member m_y oder was auch immer, so dass du nicht zwei mal den gleichen Namen für verschiedenen Dinge verwendest.

    m_ als Präfix für Membervariablen ist nicht unüblich, es gibt aber auch viele Meinungen dagegen.

    Danke für die Erklärung, und wieder etwas gelernt.



  • Dank eurer Hilfe konnte ich die Übung erfolgreich machen. Hier der Code:

    #include "stdafx.h"
    #include "std_lib_facilities.h"
    
    struct Date{
    	int y,m,d;
    	Date(int y,int m,int d);
    	void add_day(int n);
    };
    
    Date::Date(int y,int m,int d)  // prüft auf gültiges Datum und initialisiert es
    {
    	if(y<1200 || y>2200 || m<1 || m>12 || d<1 || d>31)
    	{
    		this->y = 0;
    		this->m = 0;
    		this->d = 0;
    	}
    	else
    	{
    		this->y = y;
    		this->m = m;
    		this->d = d;
    	}
    }
    
    void Date::add_day(int n) // erhöhe Date um n Tage
    {	
    	this->d = d;
    	d = d + n;
    }
    
    ostream& operator<<(ostream& os, const Date& d)
    {
    	return os << '"' << d.d << '"' << '\n';
    }
    
    void f()
    {
    	Date today(1978,6,25);
    	operator<<(cout,today);
    
    	Date tomorrow = today;
    	tomorrow.add_day(1);
    	operator<<(cout,tomorrow);
    
    	Date non(2209,8,-78);
    	operator<<(cout,non);
    }
    
    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("~");	
    }
    


  • Zwei Dinge kannst du noch verbessern:

    1. in add_day kannst du die komplette Zeile mit dem this sparen, hier heißt der Parameter ja n und d ist dann die Membervariable.

    2. Der schöne am Outputoperator ist, dass du dass

    operator<<(cout,today);
    

    auch so schreiben kannst:

    cout << today;
    

    oder sogar:

    cout << "Heute ist Tag " << today;
    


  • Danke für den Tipp, habe gleich so geschrieben. Aber eins habe ich nicht so verstanden könntest du das bitte erklären, warum brauchte in dem Konstruktor this-> und im add_day nicht? Ich vermute wegen zwei gleiche namen?



  • winux schrieb:

    Danke für den Tipp, habe gleich so geschrieben. Aber eins habe ich nicht so verstanden könntest du das bitte erklären, warum brauchte in dem Konstruktor this-> und im add_day nicht? Ich vermute wegen zwei gleiche namen?

    Ja. Im Konstruktor hast du einen Parameter mit Namen "d" und die Klasse hat eine Membervariable mit Namen "d". Der Compiler muss sich für eines der beiden Ds entscheiden und nimmt den Parameter (die Regeln dafür werden in deinem Buch vermutlich noch genannt werden). this->d sagt dann, hier meine ich die Membervaiable. In add_day gibt es keinen Parameter der "d" heißt, deshalb ist mit d ganz klar die Membervariable gemeint.



  • manni66 schrieb:

    winux schrieb:

    Danke für den Tipp, habe gleich so geschrieben. Aber eins habe ich nicht so verstanden könntest du das bitte erklären, warum brauchte in dem Konstruktor this-> und im add_day nicht? Ich vermute wegen zwei gleiche namen?

    Ja. Im Konstruktor hast du einen Parameter mit Namen "d" und die Klasse hat eine Membervariable mit Namen "d". Der Compiler muss sich für eines der beiden Ds entscheiden und nimmt den Parameter (die Regeln dafür werden in deinem Buch vermutlich noch genannt werden). this->d sagt dann, hier meine ich die Membervaiable. In add_day gibt es keinen Parameter der "d" heißt, deshalb ist mit d ganz klar die Membervariable gemeint.

    Jetzt verstehe ich es, danke für die Erklärung und für deine Hilfe.



  • Das ist die dritte Version der Date Aufgabe, und eine Frage habe ich. Ist der folgende Code korrekt? Was mich interessiert ist ob der Date Konstruktor Memberinitialisierer korrekt ist?

    class Date{
    	int y,m,d;                      // Year, Month, Day
    public:
    	Date(int yy,int mm,int dd);     // check for a valid Date and initialized it 
    	void add_day(int n);            // increase Date with n Days 
    	int month() {return m;}
    	int day() {return d;}
    	int year() {return y;}
    };
    
    Date::Date(int yy,int mm,int dd):y(yy),m(mm),d(dd)
    {
    	if(y<1200 || y>2200 || m<1 || m>12 || d<1 || d>31)
    	{
    		y = 0;
    		m = 0;
    		d = 0;
    	}
    	else {
    		y = yy;
    		m = mm;
    		d = dd;
    	}
    }
    
    void Date::add_day(int n)
    {
    	if(d + n >= 32) { d = 0;}
        else {d = d + n;}
    }
    
    ostream& operator<<(ostream& os, Date& d)
    {
    	return os << '"' << d.day() << '"' << '\n';
    }
    
    void f()
    {
    	Date today(1978,6,25);
    	cout << today;
    
    	Date tomorrow = today;
    	tomorrow.add_day(1);
    	cout << tomorrow;
    
    	Date non(2009,9,56);
    	cout << non;
    
    	Date non2(2010,10,29);
    	non2.add_day(12);
    	cout << non2;
    }
    
    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("~");	
    }
    


  • Wie wärs mit:

    cout << today;
    

    anstatt:

    operator<<(cout, today);
    


  • 314159265358979 schrieb:

    Wie wärs mit:

    cout << today;
    

    anstatt:

    operator<<(cout, today);
    

    Gerade korrigiert.



  • Ich würde an deiner Stelle das \n nicht in den operator << geben, sondern einfach

    cout << today << endl;
    

    schreiben.



  • 314159265358979 schrieb:

    Ich würde an deiner Stelle das \n nicht in den operator << geben, sondern einfach

    cout << today << endl;
    

    schreiben.

    OK gemacht, aber mich interessiert ob der Konstruktor Memberinitialisierer korrekt ist?



  • Date::Date(int yy,int mm,int dd):y(yy),m(mm),d(dd)
    {
        if(y<1200 || y>2200 || m<1 || m>12 || d<1 || d>31)
        {
            y = 0;
            m = 0;
            d = 0;
        }
        else {
            y = yy;
            m = mm;
            d = dd;
        }
    }
    

    Das ergibt keinen Sinn. Deine Membervariablen werden hier in jedem Fall 2 mal "initialisiert". Es macht auch keinen Sinn, die Werte zu überprüfen. Ein Assert reicht.



  • Und das hier, die Übung verlang eine Überprüfung der werte:

    Date::Date(int yy,int mm,int dd):y(yy),m(mm),d(dd)
    {
    	if(yy<1200 || yy>2200 || mm<1 || mm>12 || dd<1 || dd>31)
    	{
    		y = 0;
    		m = 0;
    		d = 0;
    	}
    	else {
    		yy;
    		mm;
    		dd;
    	}
    }
    


  • Ein assert ist eine ausreichende Überprüfung.



  • So weit bin ich nicht im Buch und ich weiss nicht was ein assert ist. Die Übung muss man im Konstrutor eine Überprüfung machen.



  • #include <cassert>
    
    .
    .
    .
    
    Date::Date(int yy, int mm, int dd)
    	: y(yy)
    	, m(mm)
    	, d(dd)
    {
        assert(yy >  1200 &&
    	       yy <= 2200 &&
    	       mm >  0    &&
    	       mm <= 12   &&
    	       dd >  0    &&
    	       dd <= 31);
    }
    
    .
    .
    .
    


  • bäh, verdrückt. post löschen bitte.



  • assert ist nicht dazu gedacht, Usereingaben zu kontrollieren, sondern Programmfehler zu identifizieren. Gut er macht hier zwar keine Usereingabe, aber vielleicht will er dies ja später nachholen.

    @ winux
    Was du gerade machst ist doppelt gemoppel, einmal weist du die Werte mit der Initialisierungsliste zu, und danach überprüfst du diese und überschreibst sie... Was denkst du macht das hier?

    else {
            yy;
            mm;
            dd;
        }
    

    Nichts!


Anmelden zum Antworten