für 2 Überladung(en) gibt es keine zulässige Konvertierung für den this-Zeiger



  • #include <iostream>
    #include <ctime>
    #include <string>
    #include <sstream>
    
    using namespace std;
    
    class Datum {
    private:
    	int tag_, monat_, jahr_; // Tag, Monat, Jahr
    	static int count; // Anzahl der Date-Objekte
    public:
    	bool istGueltigesDatum(int t, int m, int j);
    	inline bool istSchaltjahr(int Jahr);
    
    	Datum() {
    		tag_=1; monat_=1; jahr_=1;
    		Datum::count++; 
    		cout << "Aktuelles count: " << count << endl;
    	} // Default-Konstruktor
    	Datum(int t, int m, int j):tag_(t),monat_(m),jahr_(j){ // Tag, Monat, Jahr
    		//if(!istGueltigesDatum()){
    		//	cout << "Datum ist ungültig Default werte t=1, m=1, j=1 gesetzt" << endl;
    		//}
    		Datum::count++;
    		cout << "Aktuelles count: " << count << endl;
    	}
    	Datum(const Datum &d):tag_(d.tag_),monat_(d.monat_),jahr_(d.jahr_) { 
    		Datum::count++;
    		cout << "Aktuelles count: " << count << endl;
    	} // Kopierkonstruktor
    	~Datum() {
    		Datum::count--;
    		cout << "Aktuelles count: " << count << endl;
    	} // Destruktor
    
    	void set(int t, int m, int j){
    		tag_=t; monat_=m; jahr_=j;
    		if(!istGueltigesDatum()){
    			cout << "Ungueltiges Datum" << endl;
    			time_t tnow;
    			time(&tnow);
    			struct tm *tmnow;
    			tmnow = localtime(&tnow);
    			tag_=tmnow->tm_mday;
    			monat_=tmnow->tm_mon+1;
    			jahr_=tmnow->tm_year;
    		}
    	}// Datum explizit setzen
    
    	void aktuell(){
    		time_t tnow;
    		time(&tnow);
    		struct tm *tmnow;
    		tmnow = localtime(&tnow);
    		tag_=tmnow->tm_mday;
    		monat_=tmnow->tm_mon+1;
    		jahr_=tmnow->tm_year;
    	}// Systemdatum setzen
    
    	bool istGueltigesDatum() const {
    		return istGueltigesDatum(this->tag_, this->monat_, this->jahr_);
    	}// Datum gueltig ?
    	bool istSchaltjahr() const {
    		return istSchaltjahr(this->jahr_);
    	}// Schaltjahr ?
    	Datum& operator++() { // Tag hochzählen, präfix
    		if(!this) return *this;
    		if(!istGueltigesDatum()){
    			cout << "Operator kann auf ein ungültiges Datum nicht ausgeführt werden" << endl;
    			return *this;
    		}
    		int monate[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    		int monatesch[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
    		if(istSchaltjahr()){
    			if(tag_==monatesch[monat_-1]){
    				tag_=1;
    				if(monat_==12){
    					monat_=1;jahr_++;
    				} else
    					monat_++;
    			} else {
    				tag_++;
    			}
    			return *this;
    		} else {
    			if(tag_==monate[monat_-1]){
    				tag_=1;
    				if(monat_==12){
    					monat_=1;this->jahr_++;
    				} else
    					monat_++;
    			} else {
    				tag_++;
    			}
    			return *this;
    		}
    	}
    	Datum operator++(int) { // Tag hochzählen, postfix
    		if(!this) return *this;
    		Datum dd(*this);
    		++(*this);
    		return dd;
    	}
    	int tag() const { return tag_; } // Tag
    	int monat() const { return monat_; } // Monat
    	int jahr() const { return jahr_; }// Jahr
    	static int givec() { return Datum::count; } // Anzahl der Date-Objekte
    
    	operator std::string() const {
    		string neu;
    		stringstream tage,monate,jahre;
    		tage << tag_; monate << monat_; jahre << jahr_;
    		neu = tage.str() + "." + monate.str() + "." + jahre.str();
    		return neu;
    	}// Typumwandlungsoperator
    };
    
    inline bool istSchaltjahr(int Jahr){
    	if ((((Jahr%100)!=0) && (Jahr%4==0)) || (Jahr%400==0))
    		return true;
    	else
    		return false;
    }
    
    bool istGueltigesDatum(int t, int m, int j){
    	m--; // wegen array zahlen
    	if(m>11 || m<0 || j<0 || t<1)
    		return false;
    	int monate[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
    	if(m==1){
    		if(istSchaltjahr(j) && t<30)
    			return true;
    		else if(!istSchaltjahr(j) && t<29)
    			return true;
    		return false;
    	}
    	if(t<=monate[m]){
    		return true;
    	}
    	return false;
    }
    
    ostream &operator<<(ostream &cout,Datum &dd){
    	if(!&dd) return cout; // oder wie stelle ich fest das es nicht instantiert ist?
    	cout << "Datum: " << dd.tag() << "." << dd.monat() << "." << dd.jahr() << endl;
    	return cout;
    }
    
    int main() { 
    	Datum d; 
    	cout<<d;
    	Datum d1(29,2,2010); 
    	cout<<d1;
    	cout<<"Jahr "<<d1.jahr()<<" Schaltjahr ? "<<boolalpha<<d1.istSchaltjahr()<<endl;
    	d1.set(29,2,2012);
    	cout<<"Jahr "<<d1.jahr()<<" Schaltjahr ? "<<boolalpha<<d1.istSchaltjahr()<<endl;
    	cout<<++d1;
    	d1++; cout<<d1;
    	cin.ignore(); return 0;
    }
    

    error C2663: 'Datum::istGueltigesDatum': für 2 Überladung(en) gibt es keine zulässige Konvertierung für den this-Zeiger
    error C2663: 'Datum::istSchaltjahr': für 2 Überladung(en) gibt es keine zulässige Konvertierung für den this-Zeiger

    Es geht mir vorrangig um die Zeilen 63-68. Er kann irgendwie die globalen Funktionen nicht in den Methoden der Klasse nutzen. 🙄 Die köpfe der 4 Funktionen sind mir so vorgegeben die kann ich also nicht verändern.

    bin über jede Hilfe dankbar 🙂



  • Du rufst innerhalb einer constanten Funktion eine nicht constante Funktion auf. Das ist unzulässig.
    Die Compilermeldung ist allerdings sehr verwirrend.

    tschüß
    Troll.Soft



  • Shinophyte schrieb:

    …
    class Datum {
        …
    public:
        bool istGueltigesDatum(int t, int m, int j);
        …
        bool istGueltigesDatum() const {
            return istGueltigesDatum(this->tag_, this->monat_, this->jahr_);
        }
        …
    };
    …
    bool istGueltigesDatum(int t, int m, int j) {
        …
    }
    

    Du hast das erste istGueltigDatum als Elementfunktion deklariert (da innerhalb einer Klasse) und dann später eine Funktion mit demselben Namen als freie Funktion definiert. Für Datum::istGueltigesDatum(int,int,int) hast Du keine Definition gegeben, was zu einem Linkerfehler führen würde. Aber Du bekommst es ja sowieso schon nicht kompiliert. Der Haken ist der, dass das istGueltigesDatum, was du in dem anderen istGueltigesDatum aufrufst, eine Elementfunktion ist. Da die Elementfunktion nicht const-qualifiziert ist, kannst Du sie von einer const-Elementfunktion nicht aufrufen.

    Lösung:

    …
    // Deklaration als FREIE Funktion
    bool istGueltigesDatum(int t, int m, int j);
    
    class Datum {
        …
    public:
        …
        bool istGueltigesDatum() const {
            return istGueltigesDatum(this->tag_, this->monat_, this->jahr_);
        }
        …
    };
    …
    bool istGueltigesDatum(int t, int m, int j) {
        …
    }
    

    kk



  • 1. Deine Anfangsinitialisierung deiner statischen member fehlt

    int Datum::count = 0;
    

    2. Funktionen, die aufgrund ihrer const-correctness keine Member verändern sollen, dürfen natürlich auch keine Funktionen aufrufen, die dies dann trotzdem tun.

    3. Funktionen, die du innerhalb deiner Klasse deklarierst und außerhalb definierst, sollten zumindest dem Klassenscope zugeordnet werden

    inline bool Datum::istSchaltjahr(int Jahr)
    [...]
    bool Datum::istGueltigesDatum(int t, int m, int j){
    [...]
    


  • Man kann's aber auch so machen:

    …
    class Datum {
        …
    public:
        int tag() const;
        int monat() const;
        int jahr() const;
        …
    };
    
    bool istGueltigesDatum(int t, int m, int j);
    
    inline bool istGueltigesDatum(Datum const& d) {
       return istGueltigesDatum(d.tag(),d.monat(),d.jahr());
    }
    

    Man muss es ja mit nicht mit Elementfunktionen übertreiben. Hier würde eine freie Funktion ausreichen.

    Lese-Tipps:
    http://www.gotw.ca/publications/mill02.htm
    http://www.gotw.ca/publications/mill08.htm

    kk



  • Also erstmal vielen danke für die schnellen antworten 🙂

    aber ich glaub ich hät es nach besser beschreiben sollen also hier der korrekte Aufgabentext zu den Zeilen 63-68

    Die Funktionen inline bool istSchaltjahr(int jahr) und bool istGueltigesDatum(int t, int m, int j) sind außerhalb
    der Klasse global zu implementieren. Die Funktion istSchaltjahr wird innerhalb der Funktion istGueltigesDatum
    benötigt. Die gleichnamigen Methoden bool istGueltigesDatum() const; und bool istSchaltjahr() const; sollen
    mittels dieser globalen Funktionen intern und bzgl. der Member tag_, monat_, jahr_ implementiert werden.

    Das mit der definition von count ist schon mal geändert danke. @BasicMan01

    wenn ich die Funtionen über der classe definiere bekomme ich wieder ganz andere Fehler...

    bool istGueltigesDatum(int t, int m, int j);
    
    class Datum {
        …
    public:
        …
        bool istGueltigesDatum() const {
            return istGueltigesDatum(this->tag_, this->monat_, this->jahr_);
        }
        …
    };
    …
    bool istGueltigesDatum(int t, int m, int j) {
        …
    }
    

    das habe ich auch schon mal ausprobiert aber dann scheint er die Funktionen gleich gar nicht zu finden 😕

    Fehler 3 error C2660: 'Datum::istGueltigesDatum': Funktion akzeptiert keine 3 Argumente
    Fehler 4 error C2660: 'Datum::istSchaltjahr': Funktion akzeptiert keine 1 Argumente



  • zunächst einmal solltest du dann die zwei Funktionsdeklarationen in deiner Klasse entfernen, welche du ja global benötigst.

    Danach sollten deine zwei Funktionen entweder
    1. komplett vor der Klasse definiert werden oder
    2. durch Vorwärtsdeklaration vorher bekannt gemacht werden,

    Denn deine Klasse kennt diese beiden Funktionen noch nicht.

    //Edit: Achso vergessen.
    innerhalb der Klasse kannst du dann mit dem Scope-Operator auf diese Funktionen
    zugreifen. ::istGueltigesDatum ... aber das find ich jetzt eher keine schöne Lösung, dass so zu machen. Mein Bauchgefühl sagt mir das.
    Mal sehen, was die anderen meinen *g*



  • Shinophyte schrieb:

    wenn ich die Funtionen über der classe definiere bekomme ich wieder ganz andere Fehler...

    bool istGueltigesDatum(int t, int m, int j);
    
    class Datum {
        …
    public:
        …
        bool istGueltigesDatum() const {
            return istGueltigesDatum(this->tag_, this->monat_, this->jahr_);
        }
        …
    };
    …
    bool istGueltigesDatum(int t, int m, int j) {
        …
    }
    

    Achte auf die Terminologie. In dem obigen Beispiel wurde die Funktion istGueltigesDatum über der Klasse DEKLARIERT und darunter DEFINIERT/IMPLEMENTIERT.

    Shinophyte schrieb:

    das habe ich auch schon mal ausprobiert aber dann scheint er die Funktionen gleich gar nicht zu finden 😕

    Fehler 3 error C2660: 'Datum::istGueltigesDatum': Funktion akzeptiert keine 3 Argumente

    Oh ja, sorry. Das liegt daran, dass Datum::istGueltigesDatum im Klassen-Scope die freie Funktion aus dem darüber liegenden Scope "verdeckt". Der Compiler findet schon eine Funktion mit diesem Namen im Klassen-Scope und hört einfach auf zu suchen. Mit dem Scope-Operator müsste es gehen

    return ::istGueltigesDatum(this->tag_, this->monat_, this->jahr_);
    

    (ungetestet).

    Die Namensauflösung ist schon nicht so trivial. Aber prinzipiell sucht der Compiler "von innen nach außen" und hört auf, sobald ein oder mehrere Funktionen im aktuell durchsuchten Scope gefunden wurden. Es gibt noch ein paar Sonderregeln, zB ADL (argument dependend lookup). In den meisten Fällen werden zusätzlich noch "associated namespaces" durchsucht. Das sind die Namensräume, in denen benutzerdefinierte Typen deklariert wurden, die als Funktionsparameter benutzt wurden. Das wird auch nochmal im 2. Artikel erklärt, den ich verlinkt hatte ("Namespaces and Interface Principle").

    kk



  • Hey supi klappt einwandfrei danke 🙂


Anmelden zum Antworten