Probleme beim Überladen von Operatoren.



  • Hallo.
    Hier mein COde.

    class cDatum
    {
    	public:
    
    		cDatum(int Tag, int Monat, int Jahr);
    		cDatum(const cDatum &datum);
    
    		int iTag, iMonat, iJahr, iTagInDerWoche;
    		string sWochtentag;		
    
    		cDatum* operator+(int &tage);
    
    	private:
    
    		bool CheckDate();
    		bool CheckSchaltjahr();
    		string GetWochentag();
    		int GetTageImMonat(int monat);
    		int GetTagInDerWoche();
    };
    

    und hier ist die funktion :

    cDatum* cDatum::operator+ (int &tage)
    {
    	cout<<"TAGE :\t"<<tage<<"\n";
        // Operator zum inkrementieren des Datums.
    
    	cDatum *temp = new cDatum(*this);
    	temp->iTag++;
    
    	if (!temp->CheckDate())
    	{
    		// Es ist ein ungültiges Datum erzeugt worden.
    		if( temp->iMonat < 12)
    		{
    			temp->iMonat++;
    			temp->iTag = 1;
    		}
    		else
    		{
    			temp->iJahr++;
    			temp->iMonat = 1;
    			temp->iTag = 1;
    		}
    	}
    
    	return temp;
    }
    

    Und nun der Aufruf :

    pDatum = new cDatum(1,1,2007);
    pDatum= pDatum + 3;
    	cout<<pDatum->iTag<<" "<<pDatum->iMonat<<" "<<pDatum->iJahr<<"\n";
    

    Was soll passieren. Nun ja ich will das datumsobjekt um 3 tage erweitern. aber es kommen nuur riesige negative zahlen heruas was für eine nicjt initialisiereung spricht.
    Was mache ich bei der verwendung bzw implementierung des "+" operators falsch.

    Dank


  • Administrator

    pDatum ist ein Zeiger. Du erhöhst diesen Zeiger um 3 * sizeof(cDatum) . Danach greifst du über diesen ins völlige Nirvana zeigende Zeiger zu und aus einem Wunder heraus funktioniert es sogar und gibt dir die Werte an dieser Speicherstelle aus. Grundsätzlich ist es undefiniertes Verhalten, welches du auslöst.

    Ich empfehle, dass du mal diesen Artikel hier liest:
    Operatoren Überladung - C++ Magazin

    Grüssli



  • zuerst einmal sollte ein operator+ keinen Zeiger sondern ein neues cdatum zurückgeben.
    Dann machst du beim Aufruf den Fehler, nämlich hier:

    pDatum= pDatum + 3;
    

    Das ist keine Addtion von Daten sondern eine Zeigeraddition. Du zeigst danach auf irgendeinen Bereich im Speicher und kannst froh sein (oder auch nicht), dass das Programm dir nicht gleich mit einem segfault oder ähnlichem um die Ohren fliegt.

    Dem Anschein nach kommst du entweder von C oder evtl. auch java, dass du alles über Zeiger machen möchtest - das ist in C++ so nicht üblich.

    /edit: mal wieder zu spät...



  • Ja klar. Mensch logisch manchmal ist man aber auch blind.

    danke eure aNtworten haben mir geholfen.



  • dercooleauswandere schrieb:

    Hier mein COde.

    Zu der Ungarischen Notation werde ich mich mal zurückhalten...

    Was du aber grundsätzlich berücksichtigen solltest ist, das du die C++ Vorgaben berücksichtigst (z.B. welchen Aufbau üblicherweise Operatoren haben, und das Zeiger keine Objekte sind).

    cDatum * pDatum = new cDatum(1,1,2007);
    pDatum = pDatum + 3;
    

    Hier erhöhst du den Zeiger, sprich die Speicheradresse im selbigen, um 3. Sicherlich nicht erwünscht. Auf Zeiger lassen sich keine Operatoren von Objekten anwenden.

    Zudem sollte man immer alle Operatoren zu einem bereich überladen. Wenn du den operator+ definierst, solltest du auch den operator operator+= implementieren.

    cDatum datum(1,1,2007);
    datum = datum + 3; // operator+
    datum += 3;        // operator+=
    

    Hinzu kommt das es üblich ist den operator+ ein Objekt, den operator+= eine Referenz auf sich selbst zurückgeben zu lassen. In der Regel ist es auch besser den operator+ als Funktion, nicht als Methode zu implementieren, und diesen über operator+= zu implementieren.

    class cDatum
    {
      public:
        cDatum & operator+=(int tage)
        {
            //...
            return * this;
        }
    };
    
    cDatum operator+(cDatum const & datum, int tage)
    {
        cDatum retval = datum;
        retval += tage;
        return retval;
    }
    cDatum operator+(int tage, cDatum const & datum)
    {
        cDatum retval = datum;
        retval += tage;
        return retval;
    }
    

    Zu guter letzt lässt dein Code noch ein Problem zu:

    cDatum datum(1,1,2007);
    datum.iMonat = 40;
    

    Datenkapselung ist nicht ohne Grund üblich (Im Zweifel durch Getter/Setter-Methoden).

    cu André


Log in to reply