C++ Operatorüberladung



  • Hallo,

    Ich habe in der Schule eine Klasse Integer geschrieben. Diese Klasse soll einen int Wert haben und sich wie ein int verhalten, dafür haben wir die Operatoren überladen. Ich habe aber ein Problem damit, denn ich habe ein Fehler der mir bewusst ist, aber wenn ich ihn ändere kommt nichts mehr raus, da er es nicht mehr ausführen möchte.

    Hier erstmal der Header und die .cpp

    #ifndef INTEGER_HPP
    #define INTEGER_HPP
    
    #include <iostream>
    
    using namespace std;
    
    class Integer
    {
        private:
            int* iptr;
    
        public:
            Integer();
            Integer(int i);
            Integer(Integer& i);
            ~Integer();
    
            int getInt();
    
            bool operator>(Integer& a);
            bool operator==(Integer& a);
    
            Integer operator-();
    
            Integer& operator+(Integer& a);
            Integer& operator-(Integer& a);
            Integer& operator=(Integer& a);
            const Integer operator++(int);
    
            friend Integer& operator*(Integer& a, Integer& b);
            friend Integer& operator/(Integer& a, Integer& b);
    
            friend ostream& operator<<(ostream& os, Integer& a);
            friend istream& operator>>(istream& is, Integer& a);
    
    };
    
    #endif // INTEGER_HPP
    
    #include "Integer.h"
    
    Integer::Integer()
    {
        iptr = new int(0);
    }
    
    Integer::Integer(int i)
    {
        iptr = new int(i);
    }
    
    Integer::Integer(Integer& i)
    {
        iptr = new int(*i.iptr);
    }
    
    Integer::~Integer()
    {
        delete iptr;
    }
    
    int Integer::getInt()
    {
        return *iptr;
    }
    
    bool Integer::operator>(Integer& a)
    {
        return (*this->iptr > *a.iptr);
    }
    
    bool Integer::operator==(Integer& a)
    {
        return (*this->iptr == *a.iptr);
    }
    
    Integer Integer::operator-()
    {
        *this->iptr = -(*this->iptr);
        return *this;
    }
    
    Integer& Integer::operator+(Integer& a)
    {
        *this->iptr = *this->iptr + *a.iptr;
        return *this;
    }
    
    Integer& Integer::operator-(Integer& a)
    {
        *this->iptr = *this->iptr - *a.iptr;
        return *this;
    }
    
    Integer& operator*(Integer& a,Integer& b)
    {
        Integer neuInteger((*a.iptr) * (*b.iptr));
        return neuInteger;
    }
    
    Integer& operator/(Integer& a,Integer& b)
    {
        Integer neuInteger((*a.iptr) / (*b.iptr));
        return neuInteger;
    }
    
    Integer& Integer::operator=(Integer& a)
    {
        *this->iptr = *a.iptr;
        return *this;
    }
    
    ostream& operator<<(ostream& os, Integer& a)
    {
        os << *a.iptr;
        return os;
    }
    
    const Integer Integer::operator++(int)
    {
        Integer neuInteger( (*(this->iptr))++ );
        return neuInteger;
    }
    
    istream& operator>>(istream& is, Integer& a)
    {
        int zahl;
        is >> zahl;
        return is;
    }
    

    Das ist das "fehlerhafte", denn ich ändere immer das Objekt mit welchem es aufgerufen wird, so dass

    Integer a(10);
    Integer b(20);
    cout << a+b<<endl;
    cout << a<< endl;
    

    Beides mal 30 ausgibt. Das ist natürlich falsch und ich habe deswegen die Klassen umgeschrieben, die Referenz vorne entfernt und ein neues Objekt erzeugt, welches ich dann zurück gegeben habe. Leider funktioniert das nun jetzt nicht mehr.

    Beispielhaft nur mal eine Funktion:

    Integer operator+(Integer& a); //.h
    
    //.cpp
    Integer Integer::operator+(Integer& a)
    {
        Integer c;
        *c.iptr = *this->iptr + *a.iptr;
        return c;
    }
    

    Die abgewandelte Form führt jetzt dazu, das er das gar nicht mehr erkennt, also die Fehlermeldung ist
    "no matching funtion for call to Integer:.Integer(Integer)
    candidates are
    Integer::Integer(Integer&)
    "

    Ein zusätzliches Problem ist, das ich die beiden externen friend Methoden nicht zum laufen bekomme, obwohl es das gleiche sein müsste wie + und - nur halt mit noch einem Objekt anstatt this.

    Ich wäre für die Hilfe sehr dankbar.

    Mit freundlichen Grüßen

    Theroth



  • Erstens: wozu das rumgepointere? Das stört doch nur! Deine Klasse Integer kann als Member einfach einen int haben. Nutze nie direkte raw-Pointer, das führt nur zu Fehlern (zu Lernzwecken ist es aber natürlich ok)!
    Wenn du es zu Lernzwecken besser mit einem Pointer machen willst, dann versuche mal, stattdessen einen std::unique_ptr<int> zu verwenden.

    Zweitens: du hast eher ein += implementiert als ein +. Beim Plus ändert sich der Wert nicht, d.h. du musst einen neuen Integer mit der Summe zurückgeben. Am einfachsten ist es normalerweise, zunächst += zu implementieren und dann ist Plus ganz einfach.

    Schau dir z.B. mal https://de.wikibooks.org/wiki/C%2B%2B-Programmierung/_Eigene_Datentypen_definieren/_Operatoren_%C3%BCberladen an.

    Auch dein unärer operator- ist verkehrt: wenn du dir -a anschaust, darf sich a dadurch nicht ändern! Der Operator sollte also const sein.

    Die Operatoren wie +,-,*,/ dürfen nie die jeweils verknüpften Objekte ändern (markiere sie jeweils als "const"). Sie returnen einen neuen Wert, also bei dir "Integer", nicht "Integer&".

    Also ums kurz zu machen: nutze unbedingt const - und überlege dir, wann du welchen Wert ändern willst oder ob nicht ein neuer Wert zurückgegeben werden muss.



  • wob schrieb:

    Nutze nie direkte raw-Pointer, das führt nur zu Fehlern

    Das ist, so wie es in seiner Absolutheit dasteht, einfach Quatsch.



  • es gibt doch einen wunderschönen artikel auch hier im forum:

    https://www.c-plusplus.net/forum/232010



  • theta schrieb:

    wob schrieb:

    Nutze nie direkte raw-Pointer, das führt nur zu Fehlern

    Das ist, so wie es in seiner Absolutheit dasteht, einfach Quatsch.

    Stimmt. Hatte vorhin keine Zeit das ausführlicher zu schreiben.

    Also: nutze keine owning Raw-Pointer! (außer du weißt, warum du es doch tun willst). Nicht-Owning Raw-Pointer sind selbstverständlich immer ok.

    Der gegebene Code hier ist aber ein Beispiel, wo man keine Pointer einsetzen sollte. Das war eigentlich mein Punkt.


Anmelden zum Antworten