Überladung von Operatoren



  • Hallo,
    ich sollte ein Programm schreiben welches in der Lage ist komplexe Zahlen zu addieren, subtrahieren, ....

    Der Konstruktor war vorgegeben.
    Das war bis dahin kein allzu großes Problem.

    Nun soll das Programm erweitert werden um Folgende Befehle in der main nutzbar zu machen:

    KomplexeZahl* a = new KomplexeZahl(23.42,42.23);
    KomplexeZahl* b = new KomplexeZahl(42.23,23.42);
    c = a + b;
    cout << a.toStr() << " + " << b.toStr() << " = " << c.toStr() << endl;

    Ich verstehe nur nicht so wirklich wohin die Reise gehen soll und wie ich das ganze am besten anpacke. Das beginnt schon damit dass ich dachte wenn ich mit Zeigern arbeite muss ich -> anstatt des Punkts verwenden.
    Die toStr() Funktion mit Leben zu füllen sollte nicht allzu schwer sein, aber mit den drei neuen Objekten a,b,c zu arbeiten ist mir nicht klar.

    Dies ist mein bisheriges Programm:

    using namespace std;

    static
    double real1tmp=0,imag1tmp=0,real2tmp=0,imag2tmp=0;
    char modus;

    class KomplexeZahl{

    private:
    double real;
    double imag;

    public:
    KomplexeZahl(double real, double imag);
    KomplexeZahl ergebnis(double,double);
    std::string toStr(); //war vorgegeben nutze ich noch nicht, soll sich aber noch ändern. hier ist mir das std::string nicht klar.

    void splitZahl(void);
    void getZahl(void);
    void ausgabe(char mode);

    char zahl[20];
    KomplexeZahl *ptrergebnis;

    KomplexeZahl *addiere(KomplexeZahl *summand)
    {real = real1tmp + real2tmp;
    imag = imag1tmp + imag2tmp;
    KomplexeZahl ergebnis(real,imag);
    modus= 43;
    return ptrergebnis;
    }

    KomplexeZahl* subtrahiere(KomplexeZahl *subtrahend)
    {real = real1tmp - real2tmp;
    imag = imag1tmp - imag2tmp;
    KomplexeZahl ergebnis(real,imag);
    modus = 45;
    return ptrergebnis;
    }

    KomplexeZahl* multipliziere(KomplexeZahl* multiplikator)
    {real = real1tmp * real2tmp;
    imag = imag1tmp * imag2tmp;
    KomplexeZahl ergebnis(real,imag);
    modus = 42;
    return ptrergebnis;
    }

    KomplexeZahl *dividiere(KomplexeZahl* divisor)
    {real = real1tmp / real2tmp;
    imag = imag1tmp / imag2tmp;
    KomplexeZahl ergebnis(real,imag);
    modus = 47;
    return ptrergebnis;
    }

    double getvar(double, double)
    {return real,imag;}

    void setvar1()
    {real1tmp = real;imag1tmp = imag;}

    void setvar2()
    {real2tmp = real;imag2tmp = imag;}
    };

    int main()
    {
    KomplexeZahl objekt(real1tmp,imag1tmp);
    KomplexeZahl *ptrobjekt;
    ptrobjekt = &objekt;

    objekt.getZahl();
    objekt.splitZahl();
    objekt.setvar1();
    objekt.getZahl();
    objekt.splitZahl();
    objekt.setvar2();
    objekt.addiere(&objekt);
    objekt.ausgabe(modus);
    objekt.subtrahiere(&objekt);
    objekt.ausgabe(modus);
    objekt.multipliziere(&objekt);
    objekt.ausgabe(modus);
    objekt.dividiere(&objekt);
    objekt.ausgabe(modus);
    return 0;
    }

    void KomplexeZahl::splitZahl()
    {
    int laengezahl = strlen(zahl);
    bool vorzeichen=0;
    char hilfstr[10]="";
    int i;
    int laengezahl = strlen(zahl);
    for (i=0; i<=laengezahl; i++)
    {
    if (zahl[i] == 43) break;
    if (zahl[i] == 45) {vorzeichen=1; break;}
    hilfstr[i]=zahl[i];
    }

    int laengehilf=0;
    laengehilf = strlen(hilfstr)+1;
    laengezahl=laengezahl-2;
    int k=0;
    char hilfstr2[10]="";
    for (laengehilf; laengehilf <= laengezahl ; laengehilf++)
    {
    hilfstr2[k]=zahl[laengehilf];
    k++;
    };
    real = atof(hilfstr);
    imag = atof(hilfstr2);
    if (vorzeichen==1) imag = imag*(-1);
    };

    void KomplexeZahl::ausgabe(char mode){
    if (imag<0) cout << mode << "\t " << real << imag << "i" << endl;
    else cout << mode << "\t " << real << "+" << imag << "i" << endl;
    };

    void KomplexeZahl::getZahl(void){
    cout << "Komplexe Zahl eingeben: z.B. '5+5i'" << endl;
    cin >> zahl;
    cout << endl;
    };

    KomplexeZahl::KomplexeZahl(double real, double imag){
    }; //Was geschieht hier?

    Falls jemand eine gute Idee hat würde ich mich freuen.

    Gruß



  • Foramtier ma deinen Code bitte. C++ tags und vernünftig einrücken.

    Edit: war das so vorgegeben? Boah, du tuhst mir echt leid!



  • da hilft auch Formatierung nichts. Ich wollte den Code selber mal grad sauberrücken und mal drüberschauen, aber das stimtm vorne und hinten nichtmals im Ansatz.

    @TE: Tu dir und deiner Umwelt den Gefallen und lerne erstmal das Paradigma der Objektorientierung. Danach schaust du dir das Thema mal im Zusammenhang mit C++ an. Und dann wirst du die aufgabe auch selbstständig lösen können.



  • Für mich hörte sich das so an, dass die das so lernen 😮



  • Das wäre noch mieser. Dann gehört der Lehrer gleich mit in die Tonne geklopft.

    Kritikpunkte:
    - using namespace std
    - statische Globals
    - Zeiger überall
    - char[] statt std::string
    - zwar eine Klasse geschrieben, aber dann doch nur imperativ "programmiert"
    - kein delete

    ... to be continued ...



  • Hallo mrpp86,

    Willkommen im C++-Forum,

    .. mein Vorschlag - für mehr reicht die Zeit nicht:

    #include <iostream>
    
    class KomplexeZahl
    {
    public:
        KomplexeZahl( double r = 0., double i = 0. )
            : real( r )
            , imag( i )
        {}
        KomplexeZahl operator+( const KomplexeZahl& b ) const
        {
            return KomplexeZahl( real + b.real, imag + b.imag );
        }
        KomplexeZahl operator-( const KomplexeZahl& b ) const
        {
            return KomplexeZahl( real - b.real, imag - b.imag );
        }
        friend std::ostream& operator<<( std::ostream& out, const KomplexeZahl& z )
        {
            out << z.real;
            if( z.imag >= 0. )
                out << "+" << z.imag;
            else
                out << "-" << -z.imag;
            return out << "i";
        }
        friend std::istream& operator>>( std::istream& in, KomplexeZahl& z )
        {
            in >> z.real; // Realteil lesen
            char op;
            if( in >> op ) // Operator lesen, der Real- und Imaginärteil trennt
            {
                if( op == '+' || op == '-' ) // Operator darf nur '+' oder '-' sein
                {
                    char i;
                    in >> z.imag >> i; // Imaginäreil und abschließendes 'i' lesen
                    if( i == 'i' ) // i muss 'i' sein
                    {
                        if( op == '-' )
                            z.imag = -z.imag; // Imaginärteil negieren bei '-'
                    }
                    else
                        in.setstate( std::ios_base::failbit ); // 'i' am Ende fehlt
                }
                else
                    in.setstate( std::ios_base::failbit ); // Operator war weder + noch -
            }
            return in;
        }
    
    private:
        double real;
        double imag;
    };
    
    int main()
    {
        using namespace std;
        KomplexeZahl z;
        for( KomplexeZahl z2; cout << "Bitte komplexe Zahl eingeben - z.B.: 2+6.5i > ", cin >> z2; z = z2 )
            cout << z << " + " << z2 << " = " << (z + z2) << endl;
        return  0;
    }
    

    😕 .. und was soll die Methode SplitZahl machen?



  • Vorab erstmal vielen Dank für die schnellen Antworten.
    Stehe noch ganz am Anfang mit C++. Habe früher nur VB C oder Matlab Programmiert und es sollte erwähnt sein, dass ich in keiner Sprache wirklich professionell Programmieren kann.
    SplitZahl soll nur Real und Imaginärteil aus dem eingegebenen String trennen.
    So wie es im Moment da steht ist Aufgabenteil a ja gelöst und die Rechnungen passen.
    Was ist mit Imperativ Programmiert gemeint?
    Das ganze Klassenthema will auch noch nicht so an mich.
    In C oder VB wäre ich schon lange fertig, aber C++ ist da doch eine Ecke anspruchsvoller. 😉



  • Anspruchsvoller ja, aber wenn du die Hürde einmal gemeistert hast und es anwenden kannst, dann löst du solche Probleme nicht mehr wie für dichg ewohnt für den einen (oder 3-4 fachen Spezialfall) sondern allgemeingültig. Dann hast du eine Klasse für Komplexe Zahlen, wo du einmal die Rechnungen reinschreibst und diese für immer gelten.

    Ok, ist jetzt etwas überspitzt geschrieben, aber kommt in etwa hin.



  • Werner Salomon schrieb:

    .. mein Vorschlag - für mehr reicht die Zeit nicht:

    Warum sind operator+ und operator- bei dir Elementfunktionen? So, wie du es gebaut hast, wäre dann KomplexeZahl(2,2)+5 aber nicht 5+KomplexeZahl(2,2) möglich.



  • krümelkacker schrieb:

    Werner Salomon schrieb:

    .. mein Vorschlag - für mehr reicht die Zeit nicht:

    Warum sind operator+ und operator- bei dir Elementfunktionen? So, wie du es gebaut hast, wäre dann KomplexeZahl(2,2)+5 aber nicht 5+KomplexeZahl(2,2) möglich.

    Hallo krümelkacker,

    aus rein pädagogischen Gründen. Das schien mir der Code zu sein, der keine groben Fehler enthält und möglichst wenig Erklärungspotential beinhaltet. Gefordert war ja nur KomplexeZahl zu addieren und dass ' KomplexeZahl(2,2)+5 ' geht, hätte man mit explicit verhindern können; aber das keyword explicit hätte mrpp86 auch nur weiter verwirrt.

    Die Probleme von mrpp86 wiegen doch viel schwerer;

    hallo mrpp86,

    ein paar Tipps, der Du ja ein wenig C kannst - wenn Du C++ programmieren möchtest, so versuche als Anfänger und am Anfang bestimmte Dinge gar nicht zu tun - als da wären:
    - benutze kein malloc und kein new (Du kannst ohne riesige Programme schreiben; Alternative sind die Container s.u.)
    - benutze keine Pointer (erst mal nicht)
    - benutze keine globalen Variablen
    - benutze keine char-arrays, jedenfalls nie um hinein zu schreiben (Alternative ist std::string)

    .. und
    - mache Dich mit rudimentärem Input & Output vertraut -> std::istream zum Lesen und std::ostream zum Schreiben (vergiss atof & Co)
    - Lerne Konstruktoren und Initialisierungslisten kennen
    - mache Dich mit den Containern des C++-Standards vertraut: std::vector, std::string, usw.

    und zum Thema Operator-Überladung haben wir doch drei schöne Artikel im Magazin.

    Gruß
    Werner


Anmelden zum Antworten