[gelöst] Überladen des ++ Operators (Prä-/Postfix)



  • volkard schrieb:

    Michael E. schrieb:

    EOutOfResources schrieb:

    Die Art es auszugeben gefällt mir 😮 .

    War klar, dass du daran rummeckerst. Es weiß doch jedes Kind, dass man operator<<(ostream&, MyType) auf jeden Fall schon erklären muss, bevor die erste eigene Ausgabe gemacht werden soll, insbesondere vor operator+ .

    Für dieses Beispiel erst den op<< bauen. Dann erst den op++ bauen. Das sagt doch nicht, daß man den op<< bauen sollte, bevor man einen op<< benutzt.
    Aber das Beispiel ist eh nicht gut gewählt.
    Eine gute Reihenfolge der Lehrinhalte zurechtzuschuggern ist schon mühsam. Aber da muß ein Autor durch.

    Die Ausgabe hier ist unabhängig von op++. ➡ s. vorigen Post.



  • Michael E. schrieb:

    EOutOfResources schrieb:

    Michael E. schrieb:

    [...]

    Er soll's lassen wenn er's nicht richtig macht...

    Tut mir Leid, aber das ist Blödsinn. Sobald Klassen eingeführt wurden, will ich Member ausgeben. Soll dann direkt operator<< überladen werden? Am besten noch bevor der Leser weiß, was public und private heißen.

    Tut mir Leid, aber das ist Blödsinn.

    cout << "val1: " << val1++ << '\n';
    cout << "val2: " << ++val2 << '\n';
    

    kann man schon verlangen, damit dieses Beispiel nicht ganz so traurig ist.

    Das hat schon wieder nichts damit zu tun, daß man den op<< von Anfang bauen müßte. Strohmannargument zum zweiten mal.



  • Michael E. schrieb:

    Die Ausgabe hier ist unabhängig von op++. ➡ s. vorigen Post.

    Deswegen kann er ja auch die Reihenfolge so machen, daß der op<< VOR dem op++ gebastelt wird. Wo ist denn das Problem, es wenigsten ein Bißchen ordentlich zu machen, außer, daß man dann ein Buch nicht in einer Nacht in die Tastatur kotzen kann.



  • volkard schrieb:

    Michael E. schrieb:

    Die Ausgabe hier ist unabhängig von op++. ➡ s. vorigen Post.

    Deswegen kann er ja auch die Reihenfolge so machen, daß der op<< VOR dem op++ gebastelt wird. Wo ist denn das Problem, es wenigsten ein Bißchen ordentlich zu machen, außer, daß man dann ein Buch nicht in einer Nacht in die Tastatur kotzen kann.

    Und was ist zu dem Zeitpunkt, bevor Operatorüberladung eingeführt wurde?



  • Michael E. schrieb:

    Und was ist zu dem Zeitpunkt, bevor Operatorüberladung eingeführt wurde?

    Schreibt er's hin und sagt, dass das später behandelt wird.

    volkard schrieb:

    Wo ist denn das Problem, es wenigsten ein Bißchen ordentlich zu machen, außer, daß man dann ein Buch nicht in einer Nacht in die Tastatur kotzen kann.

    Der Satz ist auch eine Signatur wert 👍 .



  • Michael E. schrieb:

    Und was ist zu dem Zeitpunkt, bevor Operatorüberladung eingeführt wurde?

    Arbeitszeit beginn(8,15);
    Arbeitszeit ende(17,30);
    cout << berechneDifferenzInMinuten(ende,beginn) << '\n';
    

    Uups, ich mußte ja gar keine Attribute ausgeben. Eine böse Klasse. Die verkettete Liste und der Vector mußten auch keine Attribute ausgeben. Das Spiel auch nicht. Hmm. Schon komisch. Vielleicht macht man Klassen, die Attribute ausgeben wollen, doch erst nach dem Schreiben eines op<<? Aber da bewegen wir uns schon hinein in die Planung eines Buches, das will ich nicht mir Dir weitertreiben.



  • EOutOfResources schrieb:

    Michael E. schrieb:

    Und was ist zu dem Zeitpunkt, bevor Operatorüberladung eingeführt wurde?

    Schreibt er's hin und sagt, dass das später behandelt wird.

    🙄

    volkard schrieb:

    Arbeitszeit beginn(8,15);
    Arbeitszeit ende(17,30);
    cout << berechneDifferenzInMinuten(ende,beginn) << '\n';
    

    Uups, ich mußte ja gar keine Attribute ausgeben. Eine böse Klasse. Die verkettete Liste und der Vector mußten auch keine Attribute ausgeben. Das Spiel auch nicht. Hmm. Schon komisch. Vielleicht macht man Klassen, die Attribute ausgeben wollen, doch erst nach dem Schreiben eines op<<? Aber da bewegen wir uns schon hinein in die Planung eines Buches, das will ich nicht mir Dir weitertreiben.

    Zuerst Iteratoren zu definieren, ist natürlich noch besser.



  • Michael E. schrieb:

    Zuerst Iteratoren zu definieren, ist natürlich noch besser.

    Wie kommt er jetzt auf Iteratoren?



  • Daneben.



  • volkard schrieb:

    Michael E. schrieb:

    Zuerst Iteratoren zu definieren, ist natürlich noch besser.

    Wie kommt er jetzt auf Iteratoren?

    Irgendwie müssen die Daten ja nach außen kommen. Und Getter wie vector::front, die Referenzen zurückgeben, sind nur selten sinnvoll. Etc. pp.

    Aber bitte, übertrag dein Beispiel auf den Originalcode.

    Edit:

    EOutOfResources schrieb:

    Wahrscheinlich war er durch die Bezeichner " beginn " und " ende " irritiert.

    Heute mal nicht.



  • Michael E. schrieb:

    Irgendwie müssen die Daten ja nach außen kommen.

    Dem Vector reicht zunächst at(size_t).

    Michael E. schrieb:

    Und Getter wie vector::front, die Referenzen zurückgeben, sind nur selten sinnvoll.

    Bei der Liste, die einen Stack implementiert: Doch, aber klaro. Ja keine Iteratoren!

    Michael E. schrieb:

    Etc. pp.

    Und überhapt. Du machst Dir zu wenig Gedanken bei diesem Thema; alles wirkt unstimmig und nur so dahergesagt. Bin raus.



  • volkard schrieb:

    Michael E. schrieb:

    Irgendwie müssen die Daten ja nach außen kommen.

    Dem Vector reicht zunächst at(size_t).

    Wo ist der Unterschied zu front?

    Michael E. schrieb:

    Etc. pp.

    Und überhapt. Du machst Dir zu wenig Gedanken bei diesem Thema; alles wirkt unstimmig und nur so dahergesagt. Bin raus.

    Ich brauch mir keine Gedanken um alle möglichen anderen Klasse zu machen. Du bist doch mit denen angekommen. Bezieh dich doch mal auf die Originalklasse, die ja schließlich kritisiert wurde.



  • Hätte nicht gedacht das aus dem Beitrag heute noch 4 Seiten werden...
    Der Codeschnippsel ist übrigens 1:1 aus dem Buch kopiert, so ein seltsames Bsp. hätte ich mir selber nicht einfallen lassen (können).
    int main (void) {... würde ich selber auch nie so schreiben :p
    Falls jemand Interesse hat, das Buch ist absofort für einen geringen Obulus käuflich bei mir zu erwerben 🙄
    Ich hoffe zumindest ich bekomm bei eBay noch den Neurpreis dafuer, immerhin werden dort Sachen gebraucht teurer als neu verkauft.



  • Klopapier kriege ich in besserer Qualität in jedem Supermarkt.

    Du hast mit diesem Buch richtig ins Klo gegriffen, und du solltest den Verlust als Lehrgeld auffassen. Wenn du jemanden findest, der das Buch aus humoristischen Gründen archivieren will, ist das eine Sache, aber bitte verschacher den Mist jetzt nicht an einen ahnungslosen Anfänger, der den Blödsinn darin nicht als solchen erkennen kann. Sonst dauert es nicht lange, bis die nächste arme Seele hier im Forum auftaucht und nach kurzer Zeit erkennen muss, dass der Typ, von dem sie ihr Buch auf eBay gekauft hat, es aus einem bestimmten Grund loswerden wollte (und es womöglich an den nächsten Gimpel weitervertickt). Tu der Gesellschaft einen Gefallen und mach Altpapier draus.

    Bitte.



  • seldon schrieb:

    Klopapier kriege ich in besserer Qualität in jedem Supermarkt.

    Du hast mit diesem Buch richtig ins Klo gegriffen, und du solltest den Verlust als Lehrgeld auffassen. Wenn du jemanden findest, der das Buch aus humoristischen Gründen archivieren will, ist das eine Sache, aber bitte verschacher den Mist jetzt nicht an einen ahnungslosen Anfänger, der den Blödsinn darin nicht als solchen erkennen kann. Sonst dauert es nicht lange, bis die nächste arme Seele hier im Forum auftaucht und nach kurzer Zeit erkennen muss, dass der Typ, von dem sie ihr Buch auf eBay gekauft hat, es aus einem bestimmten Grund loswerden wollte (und es womöglich an den nächsten Gimpel weitervertickt). Tu der Gesellschaft einen Gefallen und mach Altpapier draus.

    Bitte.

    Kann man nur zustimmen 👍



  • Manchmal möchte man dem Verlag ein Pamphlet schreiben, in dem man erklärt, dass sie viele andere Bücher nicht verkaufen, weil sie J.W. verkaufen...



  • Hier wird immer so auf JW herumgetrampelt. Dazu gibt es hier
    http://www.file-upload.net/download-3634225/raetsel.txt.html
    ein kleines Rätsel...



  • Er kann es ja mit dem Warnhinweis bei eBay reinstellen, dass dieses Buch fehlerhaft ist und für den Einstieg in die Programmiersprache sehr ungeeignet ist. Das würde noch etwas schlechte Werbung machen und würde manchen Leuten, die nach Büchern suchen, evtl. die Augen öffnen.

    Und zur Didaktik-Diskussion: Ich bin auch kein großer Fan davon Statements zu benutzen, die erst später erklärt werden. Der Anfänger stört sich leicht an jeder Kleinigkeit. Ich fände es besser zu sagen, dass der getter an dieser Stelle nicht die eleganteste Variante ist und man später etwas Besseres kennen lernt.

    Hat natürlich auch seine Nachteile, da der Leser ständig nicht-elegante Codefetzen sieht, das ist pädagogisch wohl nicht wertvoll. Im Kapitel zu Operatorenüberladung könnte man natürlich die Reihenfolge ändern, sodass operator<< vor operator++ eingeführt wird. Aber auch hier muss man sich überlegen, ob man nicht etwas vergisst. Möglicherweise gibt es keine Operatoren-Einführungsreihenfolge, die sich gut hintereinanderschalten lässt. Dann muss man etwas nutzen, was man erst später erklärt, auch wenn das nicht optimal ist.


  • Mod

    Eisflamme schrieb:

    Hat natürlich auch seine Nachteile, da der Leser ständig nicht-elegante Codefetzen sieht, das ist pädagogisch wohl nicht wertvoll. Im Kapitel zu Operatorenüberladung könnte man natürlich die Reihenfolge ändern, sodass operator<< vor operator++ eingeführt wird. Aber auch hier muss man sich überlegen, ob man nicht etwas vergisst. Möglicherweise gibt es keine Operatoren-Einführungsreihenfolge, die sich gut hintereinanderschalten lässt. Dann muss man etwas nutzen, was man erst später erklärt, auch wenn das nicht optimal ist.

    Das ist eben die Herausforderung, wenn man Lehrbücher schreiben möchte. Andere Lehrbücher (insbesondere die, die hier immer gelobt werden), bekommen das schließlich hin. Aber wie volkard schon passend sagte, kann man solche Bücher eben nicht in einer Nacht in die Tastatur kotzen.



  • error17 schrieb:

    Hier wird immer so auf JW herumgetrampelt. Dazu gibt es hier
    http://www.file-upload.net/download-3634225/raetsel.txt.html
    ein kleines Rätsel...

    Welches Buch ist es denn? Könnte C++ in 21 Tagen sein, oder (ich habe es nie wirklich durchgearbeitet, obwohl es seit Jahren im Regal steht)?

    Ich poste mal den Inhalt der Datei, damit sie sich nicht jeder runterladen muss:

    error17 schrieb:

    Anbei eine Auswahl von Programmbeispielen mit groben Fehlern aus einem aktuellen Lehrbuch. Das Buch hat nicht mal ein Literaturverzeichnis, will aber ein Fachbuch sein. Ein kleines Rätsel: Welches Buch ist es?

    *****************************************************
    Seite 325, mensch.h (Auszug)

    class Mensch {
       private:
       // Eigenschaften der Klasse Mensch
       char *name;   // Speicher wird zur Laufzeit reserviert
       int len;      // Länge des Namen
       unsigned int alter;
       bool geschlecht; //0 = männlich; 1 = weiblich
       public:
       Mensch( const char*, unsigned int, bool );
    // ... Rest weggelassen 
    }
    

    Kritik: interne Nutzung von char* statt string. Nachteil 1: eigenes
    Memory-Management notwendig, Nachteil 2: fehleranfällig (der Autor
    kommt selbst damit nicht klar, wie noch zu sehen)

    *****************************************************
    Seite 327

    void Mensch::erzeuge(const char* n, unsigned int a, bool g){
       // ... vom Konstruktor reservierten Speicher freigeben
       delete [] name;
       // Speicher für neuen Namen anfordern
       len = strlen(n);
       name = new char[len+1];
       strcpy( name, n );
       alter = a;
       geschlecht = g;
    }
    

    Kritik: Der Code ist nicht exception-sicher. Wenn es ein Problem bei der Speicherbeschaffung gibt, ist das Objekt zerstört, weil vorher delete [] aufgerufen wird. Diese Art Problem durchzieht das ganze Buch.

    *****************************************************

    Seite 331:

    Mensch person1("Adam", 22, Mensch::MANN );
    

    Kritik: Dazu muss man den Konstruktor sehen (Seite 325):
    Mensch( const char*, unsigned int, bool );
    Obwohl nur ein bool Parameter vorhanden ist, wird ein enum übergeben. Dabei wird die ganz interne Kenntnis ausgenutzt, dass Mensch::MANN implizit auf 0 bzw. false abgebildet wird. D.h. die Reihenfolge MANN, FRAU in der enum-Deklaration
    ist entscheidend!

    *****************************************************
    Seite 331:

    // Zuweisungsoperator überladen - Defintion
    Mensch& Mensch::operator=( const Mensch& person ) {
       // Auf Selbst-Zuweisung überprüfen
       if( this == &person ) {
          return *this;
       }
       else {
          len = person.len;
          name = new char[len+1];
          strcpy( name, person.name ); 
          alter = person.alter;
          geschlecht = person.geschlecht; 
          return *this;
       }
    }
    

    Kritik: Memory-Leak. Der alte Speicher wird nicht gelöscht. Dieser Fehler kommt oft vor.

    *****************************************************

    Seite 361: String-Klasse mit char*-Attribut, aber OHNE Zuweisungsoperator, obwohl der schon behandelt wurde. Eine Zuweisung führt daher zum Memory-Leak und fehlerhaften Destruktor-Aufruf.

    *****************************************************
    Seite 375 ganz oben: ( Postfix-Operator ++)

    myComplex& operator++(int) {
       // Für den Rückgabewert
       myComplex tmp(*this);
       // Originalwerte ändern
       _real++;
       _image++;
       // ursprünglichen wert zurückgeben
       return tmp;
    }
    

    Kritik: Crash-Gefahr! Rückgabe einer lokalen Variablen per Referenz!

    *****************************************************

    Seite 379:

    // Überladung des Indexoperators 
       const char& operator[](unsigned int index) const {
           static char q = '?';
           // Indexüberprüfung
           if( (index >= 0) && (index < len) )
              return buffer[index];
           // Im Fehlerfalle ein Fragezeichen zurückgeben
           return q;
       }
    

    Kritik:

    1. Die Abfrage (index >= 0) ist schwachsinnig, weil index als unsigned int IMMER >= 0 ist.

    2. Der Index-Operator blödsinnig konstruiert. Wenn z.B. die Position 1000 im String "Wie geht es Dir? Gut?" abgefragt wird, ist dem Aufrufer nicht klar, ob er ein Fragezeichen gefunden hat oder ob ein Fehler vorliegt. Das hat natürlich mit C++ nix zu tu, so etwas ist in jeder Programmiersprache unsinnig.

    *****************************************************

    Seite 471, Zeichnung: Dass Wurst und Brot von Supermarkt erben, hat mit objektorientiertem Design nichts zu tun. Der Autor sollte mal ein Buch zur Objektorientierung lesen.

    *****************************************************
    es gibt noch mehr ... ... aber nicht hier. Das kann jemand anders ergänzen.


Anmelden zum Antworten