komplexe Zahlen



  • Ich konnte dem Übungsgruppenleiter per Mail noch die Hinweise entlocken, dass in die hpp-Datei noch die Zeile

    friend ostream &operator<< ( ostream &, const Komplexezahl &);

    eingefügt werden muss, und in cpp

    ostream &operator<< ( ostream &ostr, const Komplexezahl &a)
    {
        ostr << a.r;
        if(a.i>=0) ostr << "+";
        ostr << a.i << "j";
        return ostr;
    };
    

    Ich versteh zwar nur Bahnhof, aber immerhin läuft es jetzt.

    Nun soll das Programm aber noch erweitert werden um den Zuweisungsoperatot "=". Dafür hab ich in cpp hinzugefügt:

    Komplexezahl Komplexezahl::operator = (Komplexezahl z)
    {   Komplexezahl erg(r=z.r, i=z.i);
        return erg;
    };
    

    und die entsprechende Deklaration in hpp. (Müsste doch so stimmen?). Jetzt soll die Funktion aber auch in der main-Methode getestet werden - da fehlt mir gerade so ein bisschen die Idee wie das gehen könnte...



  • Francisca93 schrieb:

    Ich versteh zwar nur Bahnhof, aber immerhin läuft es jetzt.

    Das ist schlecht, denn dann hilft es dir ja nicht weiter. Warum überhaupt "friend"? Suche mal nach: "Prefer writing nonmember nonfriend functions"!

    Nun soll das Programm aber noch erweitert werden um den Zuweisungsoperatot "=". Dafür hab ich in cpp hinzugefügt:

    Komplexezahl Komplexezahl::operator = (Komplexezahl z)
    {   Komplexezahl erg(r=z.r, i=z.i);
        return erg;
    };
    

    und die entsprechende Deklaration in hpp. (Müsste doch so stimmen?).

    Nein, das ist so nicht richtig. Der operator= soll doch das Objekt, auf das er angewendet wird, ändern und auch zurückgeben. Erkläre mal, was hier passiert bzw. passieren soll bzw. warum du diese Zeile so geschrieben hast: Komplexezahl erg(r=z.r, i=z.i);

    Lies dir durch und versuche zu verstehen:
    a) http://en.cppreference.com/w/cpp/language/operators und http://en.cppreference.com/w/cpp/language/operator_assignment
    b) https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading

    Dazu gibt es bestimmt noch viel mehr Erklärungen.



  • Erkläre mal, was hier passiert bzw. passieren soll bzw. warum du diese Zeile so geschrieben hast: Komplexezahl erg(r=z.r, i=z.i);

    Naja, z1=z2 soll ja die Abkürzung sein für z1.operator=(z2)

    Auf z1 wird der Operator angewendet, und z2 wird als Argument übergeben (so wie bei + und - auch). So müsste ja dann der Realteil der als Argument übergebenen Zahl den Realteil der ersten überschreiben, und beim Imaginärteil genauso?



  • Richtig, der ersten. Du aber erstellst eine neue Zahl und änderst die erste Zahl nicht.



  • Doch sicher wird die erste Zahl geändert. Wegen der beiden Zuweisungen innerhalb der Parameter des Konstruktoraufrufs der Kopie. Oder irre ich? Ist auch egal: das würde ich so niemals schreiben, das verwirrt doch nur!



  • Francisca93 schrieb:

    Erkläre mal, was hier passiert bzw. passieren soll bzw. warum du diese Zeile so geschrieben hast: Komplexezahl erg(r=z.r, i=z.i);

    Naja, z1=z2 soll ja die Abkürzung sein für z1.operator=(z2)

    Auf z1 wird der Operator angewendet, und z2 wird als Argument übergeben (so wie bei + und - auch). So müsste ja dann der Realteil der als Argument übergebenen Zahl den Realteil der ersten überschreiben, und beim Imaginärteil genauso?

    Wie gut, dass du an meiner Frage vorbei antwortest... z1 und z2 kommen beide in der Zeile nicht vor.



  • z1 und z2 waren nur Beispiele für beliebige komplexe Zahlen. Du kannst es von mir aus auch a und b nennen.

    Zum "testen" hab ich jetzt in die main-Methode unten noch diese Zeilen eingefügt:

    z1=z2;
        cout << "\n\n\tz1 neu: "<< z1;*/
    

    Das scheint zu funktionieren. Es wird dann Real- und Imaginärteil von z2 angezeigt, obwohl z1 ausgegeben wurde. Das ist doch gerade das, was der Zuweisungsoperator machen soll?



  • Francisca93 schrieb:

    Erkläre mal, was hier passiert bzw. passieren soll bzw. warum du diese Zeile so geschrieben hast: Komplexezahl erg(r=z.r, i=z.i);

    Naja, z1=z2 soll ja die Abkürzung sein für z1.operator=(z2)

    Auf z1 wird der Operator angewendet, und z2 wird als Argument übergeben (so wie bei + und - auch). So müsste ja dann der Realteil der als Argument übergebenen Zahl den Realteil der ersten überschreiben, und beim Imaginärteil genauso?

    Genau, z1 = z2 soll eine Abkürzung sein für z1.operator=(z2), aber es gibt Unterschiede zwischen dem + Operator und dem = Operator.

    Der + Operator bekommt, je nach Implementierung, zwei Parameter, (oder als Member Implementierung einen) und erstellt ein neues Objekt der Klasse. Die Summanden sollen ja schließlich ihre Werte nicht ändern.

    Der = Operator ändert ein bereits bestehendes Objekt so, dass es den selben Zustand, wie das Übergebene Objekt hat.

    An welcher Stelle überschreibst du den Real und Imaginärteil in deinem Operator aufruf? Tipp: wob hat das schon verraten.

    Edit:

    Francisca93 schrieb:

    Das scheint zu funktionieren. Es wird dann Real- und Imaginärteil von z2 angezeigt, obwohl z1 ausgegeben wurde. Das ist doch gerade das, was der Zuweisungsoperator machen soll?

    Das ist, was der Operator machen soll, allerdings ist der Großteil deines Codes dafür völlig unerheblich und sorgt eher für Verwirrung.



  • wob schrieb:

    Francisca93 schrieb:

    Erkläre mal, was hier passiert bzw. passieren soll bzw. warum du diese Zeile so geschrieben hast: Komplexezahl erg(r=z.r, i=z.i);

    Naja, z1=z2 soll ja die Abkürzung sein für z1.operator=(z2)

    Auf z1 wird der Operator angewendet, und z2 wird als Argument übergeben (so wie bei + und - auch). So müsste ja dann der Realteil der als Argument übergebenen Zahl den Realteil der ersten überschreiben, und beim Imaginärteil genauso?

    Wie gut, dass du an meiner Frage vorbei antwortest... z1 und z2 kommen beide in der Zeile nicht vor.

    müssen sie auch nicht. Der Operator ist eine Memberfunktion und r sowie i sind Member. Daher steht da implizit

    Komplexezahl erg(this->r=z.r, this->i=z.i);

    Und "z" ist der übergebene Parameter, steht also in dem Beispiel für "z2".

    Aber ja, man muss schon sehr genau hinschauen, um das zu erkennen.


  • Mod

    daddy_felix schrieb:

    Aber ja, man muss schon sehr genau hinschauen, um das zu erkennen.

    Vor allem habe ich stark den Verdacht, dass da nur der Zufall am Werk war. Sieht doch sehr danach aus, als hätte da jemand named parameters (a la Python und anderen Sprachen) benutzen wollen und es kam unbeabsichtigt die korrekte Zuweisung heraus.

    Leider ist Francisca93 nicht auf die Frage eingegangen, was der Plan hinter dieser Zeile war.



  • daddy_felix schrieb:

    wob schrieb:

    Wie gut, dass du an meiner Frage vorbei antwortest... z1 und z2 kommen beide in der Zeile nicht vor.

    müssen sie auch nicht.

    Das sehe ich anders. Wenn ich nach A frage und du irgendwas zu B erklärst, passt das auch nicht.

    Ich hatte mit meiner Frage bezwecken wollen, dass genau diese Zeile erklärt wird und dabei hoffentlich klar wird, warum was wie passiert. Die Antwort von Francesca geht aber gar nicht auf diese Zeile ein, sondern beschreibt nur generelles Blabla, was die gesamte Funktion tun soll. Eine Antwort, die diese Zeile beschreibt, enthält Erklärungen, was erg ist, was r=z.r bedeutet usw. Sie könnte also anfangen mit "Es wird ein neues Objekt vom Typ Komplexezahl namens erg erzeugt. Dazu wird der Konstruktor, der 2 doubles als Parameter hat, aufgerufen. Als Parameter werden übergeben: ..." Damit sollte klar werden, warum das so zumindest ansatzweise funktioniert (ich habe nämlich dieselbe Befürchtung wie SeppJ bzgl. Named Parameter)

    Die ... sind dann der interessante Teil der Beschreibung.



  • SeppJ schrieb:

    Leider ist Francisca93 nicht auf die Frage eingegangen, was der Plan hinter dieser Zeile war.

    Einen Plan gab es nicht, es war nur so eine Eingebung 😉


  • Mod

    Francisca93 schrieb:

    SeppJ schrieb:

    Leider ist Francisca93 nicht auf die Frage eingegangen, was der Plan hinter dieser Zeile war.

    Einen Plan gab es nicht, es war nur so eine Eingebung 😉

    Wie man so schön sagt: Wenn du selber Code schreibst, musst du ihn auch verstehen. Code ist kein Haufen von wahllos zusammengeschmissenen Buchstaben und Zeichen, Code ist Logik pur. Du musst genau wissen, warum du wo und welches Zeichen setzt.

    Hier gibt es gleich mehrere Zeilen, die nur geraten sind. Zufällig machen sie auch das, was du gewünscht hast. Aber der korrekte Teil war keine Absicht und ist daher so subtil versteckt, dass selbst mehrere Erfahrene Programmierer in diesem Thread eine Weile gebraucht haben, um zu sehen, warum das überhaupt funktionierte. Außerdem viel schlimmer: Der Code macht noch eine ganze Menge anderes Zeugs, das hier gewiss unerwünscht ist! Es ist dir bloß noch nicht aufgefallen bei deinen Tests.

    Daher: Denk doch noch mal gründlich darüber nach, was du erreichen möchtest, wie das geht, und was jetzt stattdessen passiert.



  • Habe das Testat inzwischen bekommen, also ganz so schlimm kann mein Programm nicht gewesen sein 🙂

    Es war ja auch ein z.T. vorgegebener Text, der erweitert werden sollte. Das "using namespace std" war übrigens auch im Skript enthalten, also kann man wohl annehmen, dass der Professor es schön findet, auch wenn einige hier es anders sehen.



  • Francisca93 schrieb:

    Habe das Testat inzwischen bekommen, also ganz so schlimm kann mein Programm nicht gewesen sein 🙂

    Es war ja auch ein z.T. vorgegebener Text, der erweitert werden sollte. Das "using namespace std" war übrigens auch im Skript enthalten, also kann man wohl annehmen, dass der Professor es schön findet, auch wenn einige hier es anders sehen.

    Was für eine ekelhafte Mentalität.
    Aber was solls - Interesse am Programmieren hast du offensichtlich eh keine und dementsprechend wird es, zum Glück, auch nie irgendwo Code von dir geben, den dann irgendwer korrigieren muss.
    Von daher - viel Erfolg bei den nächsten Testaten und der Prüfung.



  • häreichtdoch schrieb:

    Francisca93 schrieb:

    Habe das Testat inzwischen bekommen, also ganz so schlimm kann mein Programm nicht gewesen sein 🙂

    Es war ja auch ein z.T. vorgegebener Text, der erweitert werden sollte. Das "using namespace std" war übrigens auch im Skript enthalten, also kann man wohl annehmen, dass der Professor es schön findet, auch wenn einige hier es anders sehen.

    Was für eine ekelhafte Mentalität.
    Aber was solls - Interesse am Programmieren hast du offensichtlich eh keine und dementsprechend wird es, zum Glück, auch nie irgendwo Code von dir geben, den dann irgendwer korrigieren muss.
    Von daher - viel Erfolg bei den nächsten Testaten und der Prüfung.

    Tja, mein Lieber, du wirst die Realität akzeptieren müssen, dass die Welt nicht nur aus Programmier-Nerds besteht 😉 . Es gibt eben Studiengänge (wie bei mir ET) wo die Programmier-Module in erster Linie Pflichtveranstaltungen sind.

    Warst du in deinem Info-Studium von jedem Fach hellauf begeistert, von Mathe über Physik bis Englisch? Und das von Anfang an, und auch bei didaktisch katastrophalen Dozenten?

    Ich habe ja noch nicht mal gesagt, dass ich Programmieren grundsätzlich nicht mag, es ist halt am Anfang schwierig.



  • Du hast einfach nicht verstanden, was du gemacht hast und zufällig das richtige Ergebnis bekommen. Spätestens in der Klausur fällst du damit auf die Schnauze.
    Bei mehreren hundert Studenten können die Lehrenden halt nur Ergebnisse kontrollieren, habe ich meiner Zeit als Tutor teilweise nicht anders machen können. In der Prüfung sieht man dann, wer es verstanden hat.

    Die Aussage: 'Was für eine ekelhafte Mentalität" wird sich auch nicht aufs programmieren beziehen, sondern auf die Arbeitseinstellung. Niemand will Kollegen haben, die nicht wissen ob und warum ihre Arbeitsergebnisse stimmen oder nicht stimmen. Das gilt auch für Aufgaben, die man machen muss und nicht unbedingt das sind, was man machen möchte.



  • Francisca93 schrieb:

    Tja, mein Lieber, du wirst die Realität akzeptieren müssen, dass die Welt nicht nur aus Programmier-Nerds besteht 😉 . Es gibt eben Studiengänge (wie bei mir ET) wo die Programmier-Module in erster Linie Pflichtveranstaltungen sind.

    Ne, das ist gar nicht das, was ich akzeptieren muss. Was ich akzeptieren muss und längst akzeptiert habe, da natürlich schön länger bekannt: Die Welt besteht nicht nur aus wohl erzogenen Menschen, es gibt auch die, die nach Hilfe fragen, Hilfe bekommen und sich dann mit keinem Wort bedanken aber mit einem "Ach was redet ihr, Testat wurde doch akzeptiert :)" wieder abhauen.
    Komischerweise machen das selten die "Nerds", wie du sie nennst - denn gerade die "Nerds", denen man ja so oft geringe Sozialkompetenz vorwirft, sind meistens gerade die, die genug Anstand haben.

    Was deine Interesse an Programmieren angeht: Dein Code ist immer noch schlecht, aber da das Testat ja akzeptiert wurde, ist das uninteressant. Klar, dein Interesse scheint riesig zu sein.


  • Mod

    Ich denke, alle haben ihre Meinung über den Charakter des jeweils anderen ausreichend zum Ausdruck gebracht. Es besteht kein Grund, hinterher zu treten. Da fachlich nichts weiter zu erwarten ist, mache ich zu.


Anmelden zum Antworten