> Operator-Überladung funktioniert nur gut auf
> Werten die einen Ring bilden, im mathematischen Sinne.
Und zwingt dich jemand dazu, es für andere Objekte anzuwenden? Was
schadet denn eine Möglichkeit in der Programmiersprache, wenn an sie
in der eigenen Anwendung nicht nützt?
Ach ja, noch ein anders schönes Beispiel, wo das Ueberladen der
Operatoren sinnvoll ist, obwohl es sich nicht um einen Ring handelt:
der -> Operator und der * Operator bei smart Pointern.
Eins hab ich noch: der [] Operator bei Containern.
Und noch einen: der () Operator bei statusbehafteten Callbacks.
Was man natürlich auch gerne vergisst: Iteratoren sind ohne die
überladenen Operatoren *, ->, +, ++, --, und - so auch nicht drin.
> In meiner
> Praxis als Programmierer ist mir das genau nie über den Weg gelaufen.
Mir schon öfter. Also gibt es Fälle, wo man das brauchen kann. Für
alle anderen Fälle stellt die Möglichkeit der Operatorüberladung
keine zusätzliche Komplexität dar - einfach nicht benützen. Wo ist
das Problem?
> > > Stack vs. Heap Allocation,
> >
> > Wo ist das Problem?
>
> Das Problem ist, dass ich mich darum kümmern muss, und es zu subtilen
> Probleme führt wenn es jemand falsch macht.
Damit hatte ich bisher noch nie Probleme. Aber OK, man könnte das vor
dem Programmierer verbergen. Dann ist allerdings das Problem, wann
man auf diese Weise dynamisch auf dem Heap allozierte Objekte wieder
freigeben kann. Den Compiler möchte ich nicht schreiben.
> > > dangling pointers,
> >
> > Eine Folge schlechten Memory Managements.
>
> Ja. Aber wieder Komplexität, die nicht nötig gewesen wäre. Und in
> jedem nicht trivialen Projekt rennt man irgendwann in solche Probleme
> rein.
Also ich habe ja schon so manches nicht triviale Projekt bearbeitet.
Dangling Pointers hab ich auch schon zu genüge gesehen - in Code, der
nicht ordentlich Designed war. Nachdem ich da mit meinem Refactoring
fertig war, war auch in allen Fällen ganz offentsichtlich, wo der
Fehler liegt und er konnte einfach behoben werden.
Für eine vermurkste Softwarearchitektur kann keine Sprache was -
nicht mal Java.
> Die Zeit, die man dann mit debugging verbringt könnte man auch
> in Features oder Freizeit investieren.
Oder vorher in ein Buch. Alternativ in Nachdenken über eine für das
Problem geeignete Softwarearchitektur.
> > > mäßige libraries,
> >
> > Was genau fehlt dir, oder ist dir nicht gut genug?
>
> Boost und stdlib sind ja im Prinzip ganz nett, aber wenn du das mit
> der Class Library bei Java, C#, Python oder Ruby vergleichst hat es
> nicht im entferntesten vergleichbare Funktionalität. Das kann man
> sich sicher in C++ auch zusammensuchen, aber "batteries included" ist
> ein feature.
Noch mal: was konkret fehlt dir?
> > > include files,
> >
> > Wo ist das Problem?
>
> Ewige Compile-Zeiten, Abhängigkeiten von der Include-Reihenfolge, der
> ganze Dependency-Wahnsinn.
Ein ordentliches Makefile, oder alternativ Tools wie cmake, die das
ordentliche makefile erzeugen, helfen da ganz gut weiter. Mit make -j
8 (z.B. auf einem 8 Core System) wird auch schön alles parallel
gebaut.
Versuch mal mit Java make -j 8 einzusetzen. Hab ich gemacht. Das
Ergebnis waren einige völlig kaputte class files, weil zwei Java
Compiler gleichzeitig darauf herumgebastelt und sich gegenseitig
gestört haben.
Ausserdem wurden einige Files mehrfach compiliert, weil der erste
Prozess noch festgestellt hat, dass die Datei erneuert werden müsste,
währen der zweite gerade dabei war, genau das anzufangen. Das hat
natürlich die Compilezeit nicht gerade verkürzt.
> Wo wir grade vom Compiler sprechen: ein tolles feature eine
> Programmiersprache ist auch, wenn man Source Code tatsächlich mit
> vertretbarem Aufwand parsen kann. Das hat bei Java zu einer
> unglaublichen Vielfalt geführt - hervorragende IDEs, statische
> Codeanalyse, Generators, usw.
OK, akzeptiert, wobei dei entsprechenden Tools für C++ nicht schlecht
sind. Zugegeben sind sie aber deutlich schwerer zu entwickeln als die
entsprechenden Java Varianten.
> > > der ganze const Schlamassel.
> >
> > const erlaubt dem Compiler sehr effiziente Optimierungen. Es ist also
> > sinnvoll, das auch in der Sprache zu haben. Wo ist dein Problem
> > damit?
>
> Extrem unintuitive Deklarationen, und dann doch wieder volatile?
Was ist einfacher und klarer als "const int myConstantInteger"? Warum
findest du das unintuitiv? Was wäre besser?
Und ja, man kann const auch mit Gewalt wieder weg kriegen, aber
niemand zwingt dich dazu das zu machen. Ich verlasse mich auf const
und wenn einer, der meine Klassen benützt meint, er müsse da toll
herumtricksen, ist das sein Problem, wenn es dann nicht geht.
> In Sprachen ohne Pointerarithmetik und mit echter Laufzeitumgebung
> kriegt der Compiler solche Optimierungen auch ohne Babysitting durch
> den User hin.
Nur in den wirklich offensichtlichen Fällen. Abgesehen davon halte
ich es durchaus für ein Feature, wenn die Schnittstelle einer Klasse
klar deklariert, dass eine Methode z.B. das Objekt nicht ändert, oder
dass ein Objekt, da als per Referenz Parameter übergeben wird, nicht
geändert wird.
Wie macht man das in Java? Wenn man Glück hat, steht es im Kommentar
zur Methode.
> Schlechten Code kriegt man in jeder Sprache hin. [...] Das gilt auch für Python
> oder Ruby, wobei man sich da dann wieder Sorgen um die Performance
> machen muss...
Ruby kenne ich wieder nicht so gut, aber Python ist eine ganz andere
Nummer als Java. Das ist eine wirklich gelungene Sprache und sie hat
neben vielem andern auch - oh wunder oh wunder - Mehrfachvererbung
und Operatorüberladung.
So Dinge wie Pointerarithmetik und eigene Speicherverwaltung hat sie
nicht, weil sie als Skriptsprache nicht darauf ausgelegt ist, auch
extrem effizienten Code schreiben zu können. In solchen Fällen kann
man ja auch Module zurückgreifen, die man z.B. in C++ schreibt.
> Das Problem ist immer, dass man beim "benchmarketing" praktisch alles
> und nichts beweisen kann. Es gab auf jeden Fall schon Benchmarks in
> denen Java schneller war,
Die hab ich auch mal gesehen. Da haben die also auf einer recht
modernen Maschine den C++ Code mit suboptimalen Optimierungen für den
386er (ohne MMX, ohne SSE, ohne Instrunction reordering, mit nur
minimalen Instruction Caches etc.) übersetzt und sich dann gewundert,
dass die Hot Spot Engine von Sun, dei zur Laufzeit natürlich den
Prozessor kennt und für den mit seinen Fähigkeiten optimieren kann,
einen vergleichbaren Code schneller ausgeführt hat. Toll.
Abgesehen davon war der Code Java mässig geschrieben und dann nur
syntaktisch an C++ angepasst, statt für beide Sprachen das von
versierten Programmierern mit Erfahrung in der jeweiligen Sprache
umzusetzen. Die Möglichkeiten von C++ hat man also nicht konsequent
genützt.
> Es gibt auch eine ganze Reihe von eher theoretischen Argumenten,
Die sich aber in der Praxis noch nicht bestätigt haben.