NULL
-
+fricky schrieb:
...aber ich bezweifle, dass jemand, der Bescheid weiß mal aus Versehen Operatorenüberladung verwendet.
nicht aus versehen, für den verfasser verständlich und einleuchtend, für andere leser (und verwender) des codes möglicherweise schwer durchschaubar und mit seltsamen nebeneffekten verbunden. z.b. haste das problem bei 'nem überladenen operator, wer das resultat wieder freigeben soll, wenn's nicht mehr gebraucht wird. oder was passiert, wenn die operation schiefgeht usw. d.h. du musst dir viele gedanken machen, wenn du op-overloading sinnvoll einsetzen willst, damit der benutzer es intuitiv verwenden kann, ohne in irgendwelche fallen zu tapsen.
Freigegeben wird alles automatisch, beim Fehler fliegt 'ne Exception. Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").
-
Vielleicht sollte fricky mal diesen Artikel lesen:
http://magazin.c-plusplus.net/artikel/%DCberladung%20von%20Operatoren%20in%20CPlusPlus%20(Teil%201)Allerdings erscheint mir die ganze Diskussion sowieso ein wenig überflüssig zu sein. Hier kommen überall Argumente von Leuten, welche sich mit der Sprache, über welche sie argumentieren, so gut wie nicht beschäftigt haben. fricky ist meiner Meinung nach der beste Kandidat für so eine Person
C++ ist nicht perfekt, C ist nicht perfekt und Java ist nicht perfekt. Damit wäre die Diskussion eigentlich schon zusammengefasst. Ah, nein, habe was vergessen. Die fanatischen Anhänger der Sprachen denken jeweils, dass ihre Sprache besser wäre, als die anderen. So, jetzt ist es zusammengefasst
Grüssli
-
+fricky schrieb:
C++ aber auch nicht, hat's alles von C übernommen, bis auf die kleine ausnahme mit dem void*
Haha, Du kennst C++ doch gar nicht richtig!
-
supertux schrieb:
Oder kannst du eine Java Referenz auf jede beliebige Addresse des Addressraums zeigen lassen?
Java Referenzen folgen der Semantik und Syntax der Pascal-Zeiger! Man kann lediglich keine Zeigerarithmetik wie in C machen, was per se kein Nachteil ist. Typsicherheit gilt für Zeiger (Java Referenzen) ebenfalls, aber das trifft auf andere Sprachen mit Zeiger auch zu.
-
+fricky schrieb:
nö, in Java benutzt man dafür interfaces.
Interfaces sind Mehrfachvererbung für Arme. Wenn man ein SmartPointer verwendet hat man keine Abhängigkeit im Sinne "erbt von" sondern "beinhaltet". Java muß man da auch Zeiger (Referenzen) verwenden. Bei Fowler & Co. finden sich Hinweise zum passenden Entwurf von Klassen.
-
+fricky schrieb:
achso, noch mal 'ne frage zu c++ operatorüberladung: angenommen ich mache mir mit C++ 'ne klasse, die sinnvoll überladene shift-operatoren haben könnte (z.b. eine art schieberegister-simulation). kann ich den << zusätzlich noch als 'stream-output' operator überladen. ich meine ungefähr so:
Ja, das geht problemlos, da die Typen der Argumente unterschiedlich sind.
Den operator<< definiert man üblicherweise als reine Funktion, man kann ihn auch als Methode definieren, aber das hat andere Vor-/Nachteile.
-
Badestrand schrieb:
Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").
ich schon, z.b. eine klasse für komplexe zahlen, die den ^-operator (xor) zum potenzieren benutzt. und dieses stream-i/o zeugs << und >> ist uns allen ja bekannt.
~john schrieb:
+fricky schrieb:
C++ aber auch nicht, hat's alles von C übernommen, bis auf die kleine ausnahme mit dem void*
Haha, Du kennst C++ doch gar nicht richtig!
es ging um's typsystem. c++ hat so gut wie nichts, was die typisierung sicherer macht, als von die von C. beide sprachen sind schwach typisiert.
~john schrieb:
+fricky schrieb:
nö, in Java benutzt man dafür interfaces.
Interfaces sind Mehrfachvererbung für Arme.
nenn es wie du willst. interfaces sind praktisch, wenn man verschiedene implementierungen für ähnliche dinge hat. du kannst damit festlegen, was ein objekt können soll, ohne konkret angeben zu müssen, um welches klasse von objekten es sich handelt.
~john schrieb:
Wenn man ein SmartPointer verwendet hat man keine Abhängigkeit im Sinne "erbt von" sondern "beinhaltet". Java muß man da auch Zeiger (Referenzen) verwenden.
wer redet hier von vererbung (ausser dir)? sicherlich verwendet java auch zeiger bzw. referenzen (sind ja sowieso das selbe), aber die brauchen nicht 'smart', sondern können ruhig ganz dumm sein, ohne das irgendwas schlimmes passiert.
-
+fricky schrieb:
Badestrand schrieb:
Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").
ich schon, z.b. eine klasse für komplexe zahlen, die den ^-operator (xor) zum potenzieren benutzt. und dieses stream-i/o zeugs << und >> ist uns allen ja bekannt.
Die Stream-Operatoren zur Ausgabe sind in C++ doch intuitiv. '^' für pow ist natürlich ein Fehltritt.
-
Badestrand schrieb:
+fricky schrieb:
Badestrand schrieb:
Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").
ich schon, z.b. eine klasse für komplexe zahlen, die den ^-operator (xor) zum potenzieren benutzt. und dieses stream-i/o zeugs << und >> ist uns allen ja bekannt.
Die Stream-Operatoren zur Ausgabe sind in C++ doch intuitiv. '^' für pow ist natürlich ein Fehltritt.
'^' für pow wäre auch intuitiv. wenn die meisten es machen würden, wäre es was ganz normales. blöd dabei ist aber, dass die rangfolge von operatoren beim überladen nicht geändert werden kann. das hat der erfinder von C++ einfach vergessen.
-
+fricky schrieb:
Badestrand schrieb:
Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").
ich schon, z.b. eine klasse für komplexe zahlen, die den ^-operator (xor) zum potenzieren benutzt. und dieses stream-i/o zeugs << und >> ist uns allen ja bekannt.
Link, falls es bei der in der Firma passiert ist, poste es bitte auf thedailywtf.com
-
+fricky schrieb:
blöd dabei ist aber, dass die rangfolge von operatoren beim überladen nicht geändert werden kann. das hat der erfinder von C++ einfach vergessen.
Du wetterst gegen Operatorüberladung weil es den Code ja achso unleserlich macht und willst aber ganz elementare Eigenschaften dieser gleich auch noch ändern können? Ich weiss ja dass du nur trollst, aber etwas weniger offensichtlich bitte
-
Tim schrieb:
Du wetterst gegen Operatorüberladung weil es den Code ja achso unleserlich macht und willst aber ganz elementare Eigenschaften dieser gleich auch noch ändern können?
naja, es wäre doch 'ne verbesserung. dann könnte man dafür sorgen, dass ein überladener '^'-operator vor +,-,*,/, usw. kommt und ihn damit als 'pow' nutzen. die shifts werden doch auch schon anderweitig verwendet, ohne dass sich jemand dran stört.
-
+fricky schrieb:
Tim schrieb:
Du wetterst gegen Operatorüberladung weil es den Code ja achso unleserlich macht und willst aber ganz elementare Eigenschaften dieser gleich auch noch ändern können?
naja, es wäre doch 'ne verbesserung.
Nein.
Denn operatoren sind funktionen. EIne funktion multiply() hat sich immer gleich zu verhalten. Sie umzudefinieren ist genau das was an operator overloading kritisiert wird.
Nur ist das halt alles sehr kurzsichtig. denn wenn + "add" heisst und * "multiply" dann sind das ganz normale funktionen mit einem ganz bestimmten verhalten. gerade wenn man überladung nicht hat: was macht folgender code:
c=a.add(b);
ändert sich a oder ändert es sich nicht?
operator überladung verhindert zweideutigkeiten. deshalb ist sie gut.
und statt ^ fürs potenzieren hätte der autor auch dingsDasHoch() nehmen können. wäre genauso ein schlechtes interface gewesen. ^ ist dagegen wunderschön eindeutig. und es fürs potenzieren zu verwenden zeugt nur von dummheit und sonst nix.
-
Badestrand schrieb:
Die Stream-Operatoren zur Ausgabe sind in C++ doch intuitiv. '^' für pow ist natürlich ein Fehltritt.
als ich das erste Mal je C++ Code sah (hello world), war meine erste Frage: "hä? link shift mit einem String?", ich hab's einfach nicht verstanden, was das sein soll, hab's einfach so akzeptiert. Erst später ist mir klar geworden, was das war (als ich zum Oprator-Überladung Kapitel gekommen bin). So intuitiv finde (und fand ich damals) es gar nicht.
-
supertux schrieb:
Badestrand schrieb:
Die Stream-Operatoren zur Ausgabe sind in C++ doch intuitiv. '^' für pow ist natürlich ein Fehltritt.
als ich das erste Mal je C++ Code sah (hello world), war meine erste Frage: "hä? link shift mit einem String?", ich hab's einfach nicht verstanden, was das sein soll, hab's einfach so akzeptiert. Erst später ist mir klar geworden, was das war (als ich zum Oprator-Überladung Kapitel gekommen bin). So intuitiv finde (und fand ich damals) es gar nicht.
Du warst aber nur verwirrt, weil du den Shift-Operator aus einer anderen Sprache (wohl C) kannstest. Aber mit dieser Voraussetzung sollte man an eine neue Sprache nicht rangehen. Weil sonst kann man nie ne neue Sprache designen, weil immer irgendjemand meint, er kennt das aber anders.
Für mich pers. war das erste C++-Helloworld! sehr einleuchtend. Weil ich den Shift-Operator aus C nicht kannt, weil ich ebend kein C kannte (kannte nur Basic und Assembler). FÜr mich war das damals sonnenklar das der String in so ein cout "rein geht".
-
Ist ja alles richtig, aber als du dann das erste mal was gesehen hast wie 1<<30, was hast du dann gedacht? Da geht eine 30 in die 1 rein?
-
Und beim Thema shift-operatoren fandest du es auch total einleuchtend? Immerhin geht hier ja die 8 nicht in die 1 rein: 1<<8
-
tfa schrieb:
Ist ja alles richtig, aber als du dann das erste mal was gesehen hast wie 1<<30, was hast du dann gedacht? Da geht eine 30 in die 1 rein?
Es war sonnenklar, weil in dem Buch drin stand, das man damit Zahlen shiften kann. Und? Vielleicht bin ich auch nur zu doof, um das nicht zu verstehen.
C++ ist halt nichts für Schlauberger.
Aber im Ernst: C++ hat eine kontextabhängige Syntax. Das solle man schon mittlerweile mitbekommen haben.
-
Shade Of Mine schrieb:
operator überladung verhindert zweideutigkeiten. deshalb ist sie gut.
schon klar, deshalb kann man auch >> und << wahlweise als shift oder als stream-i/o operator benutzen.
supertux schrieb:
als ich das erste Mal je C++ Code sah (hello world), war meine erste Frage: "hä? link shift mit einem String?"
frag' einen C-programmierer, was a<<b macht und er wird dir sagen 'nichts, weil die zuweisung fehlt'. wenn du die selbe frage an C++ programmierer richtest, würdest du wahrscheinlich so viele verschiedene antworten bekommen, wie du leute fragst.
Artchi schrieb:
Du warst aber nur verwirrt, weil du den Shift-Operator aus einer anderen Sprache (wohl C) kannstest. Aber mit dieser Voraussetzung sollte man an eine neue Sprache nicht rangehen.
und du warst etwas später verwirrt, als du bemerktest, dass es den selben shift-op auch in C++ gibt, ne?
-
Badestrand schrieb:
Freigegeben wird alles automatisch, beim Fehler fliegt 'ne Exception. Ich hab bis jetzt noch nie Operator-Überladung gesehen, die sich nicht intuitiv verhält ("do as the ints do").
Seit wann hat C++ einen anstaendigen GC? Und ein schlechtes Sprachfaeture (C++ exceptions) mit einem anderen zu kombinieren (op. ueberladung) kommen auch nur C++ler auf die Idee. Bis jetzt gibt es immer noch keinen einiges Beispiel fuer sinnvolle op.uberladung.
Nur ist das halt alles sehr kurzsichtig. denn wenn + "add" heisst und * "multiply" dann sind das ganz normale funktionen mit einem ganz bestimmten verhalten. gerade wenn man überladung nicht hat: was macht folgender code:
c=a.add(b);
ändert sich a oder ändert es sich nicht?
c = a + b;
ändert sich a oder ändert es sich nicht? - In jeder anderen Sprache wuerde ich sagen, nein, in C++: Wer weis. Um Klarheit zu verschaffen muss ich mir die Dokumentation (wie bei jeder anderen Sprache auch) anschauen. Klar, der op+ sollte man in C++ alsconst X operator+(X const& lhs, X const& rhs);
definieren, aber ist es die Regel? Und wenn die def. Zufaellig mal den Regeln erfolgt, gibt es immer noch const_cast oder andere Tricks.
Nicht nur das sich die Def. der Operatoren unterscheiden kann, man kann sogar die Def. der gleichen Operatoren+Zuweisung veraendern. Wer garantiert mir das +,-,* und / sind genauso wie +=, -=, *= und /= verhalten?
Das viel gepriesene
Matrix a, b, c; c = a + b; // anstelle von c.add(a, b);
Was passiert wenn es schief geht? Eine Art "Fehler-Matrix" zurueck zugeben? Oder eine exception zu werfen? Eine add() Funktion koennte einfach boolean zurueck geben.
Nichtmal die C++ FAQ bringt gute Beispiele fuer op.uberladung.
http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.3* myString + yourString might concatenate two std::string objects
* myDate++ might increment a Date object
* a * b might multiply two Number objects
* a *might access an element of an Array object
* x = p might dereference a "smart pointer" that "points" to a disk record — it could seek to the location on disk where p "points" and return the appropriate record into xdir + "/" + file
das funktioniert wenn [i]dir* ein std::string und wenn file ein char* ist, aber nicht mehr wenn dir ein char* ist und file ein std::string. Ich sag nur
std::ifstream in((std::string(dir) + "/" + file).c_str())
- myDate++, was soll das? Plus ein Jahr, ein Monat, oder ein Tag? Wenn myDate++ um Tage erhoeht, wieso ist dann myDate nicht einfach ein Integer.
usw.
- myDate++, was soll das? Plus ein Jahr, ein Monat, oder ein Tag? Wenn myDate++ um Tage erhoeht, wieso ist dann myDate nicht einfach ein Integer.