C zu C++ - Einfacherer Übergang?
-
namespace invader schrieb:
Nicht wirklich. Klassen mit virtuellen Methoden sind im Grunde das Selbe wie Produkttypen und polymorphe Funktionen, die man bei der funktionalen Programmierung hat. OOP ist eigentlich nur eine in die Nähe von prozedualer Programmierung gerückte Low-Level-Sichtweise auf einen bestimmten Bestandteil funktionaler Programmierung.
Ich weiss nicht, was du damit meinst. Ist alles ziemlich schwammig.
Blöd nur, dass alle die funktionalen Sprachen immer noch Typen von Objekten kennen, die sie unterscheiden.
Bloed, dass das Konzept von Typen nichts mit Prozedural oder Funktional zu tun hat.
-
mngbd schrieb:
Blöd nur, dass alle die funktionalen Sprachen immer noch Typen von Objekten kennen, die sie unterscheiden.
ich verstehe das problem nicht.
-
Shade Of Mine schrieb:
ich verstehe das problem nicht.
Ich auch nicht. Ich wollte ja nur sagen, dass eine prozedurale Sprache genauso objektorientiert sein kann wie eine funktionale; Typtheorie hin oder her. Und es ist mir auch egal, ob manche Sprachen eine Möglichkeit beherrschen, Objektorientierung selbst zu bauen.
-
Ich meinte, dass das, was objektorientierte Programmierung ausmacht, nämlich virtuelle Methoden (und alles was damit zusammenhängt), in funktionalen Sprachen mir ordentlichem Typsystem schon implizip vorhanden sind. Deswegen "braucht" man zusätzliche OOP-Sprachfeatures bei funktionaler Programmierung nicht. Wenn es sie in funktionalen Sprachen doch gibt, sind sie mehr oder weniger nur Syntax, und kein großartiges neues Paradigma.
Das hängt natürlich auch von den konkreten Sprachen ab über die man spricht und ich will mich deswegen auch nicht streiten. Aber ich würde eben OOP nicht als orthogonal zu funktionaler Programmierung sehen.
-
@namespace invader:
warum nicht gleich so einen argumentativen und objektiven Beitrag wie den am Ende der 4. Seite? Haette uns den ganzen Flame erspartnamespace invader schrieb:
C konzentriert sich auf prozeduale Programmierung und lässt High-Level-Features wie Garbage Collection, Exceptions, Polymorphie usw. bewusst weg. Was dabei rauskommt ist eine schöne, konsistente und einfache Sprache. Sprachen wie C# und Java abstrahieren von der Low-Level-Ebene von C und konzentrieren sich eher auf objektorientierte Programmierung, womit sie wieder halbwegs schöne und einfache Sprachen sind, aber mit ganz anderen Möglichenkeiten und Beschränkungen.
C++ versucht, sehr viele Paradigmen zusammenzubringen. Wenn man tatsächlich all diese Paradigmen in einer Sprache braucht (also vor allem Sprachfeatures für OOP und gleichzeitig die Low-Level-Features von C, einschließlich Kompatibilität zu C selbst), ist das sicher nütztlich. Leider geht das nicht so problemlos, so dass es in C++ jede Menge unschöne Kompromisse und hässliche Workarounds gibt. Wenn man damit leben kann ok, aber trotzdem ist es sehr weit hergeholt, C++ pauschal als "besser als C" zu bezeichnen. Und vor allem dürfte klar sein, dass C++ um einiges schwieriger zu erlernen ist als C. Und mit Erlernen meine ich vollständiges Beherrschen, bei denen man wirklich alle Sprachfeatures und ihr zusammenwirken versteht.
Reine Neugier: was waer denn ein Beispiel eines solchen Workarounds?
Das schoene an C++ ist ja grad, dass du all die Features zur Auswahl hast, aber sie nicht benutzen musst. Ich schreibe oft und gern prozedurales C++ und wage zu behaupten dass das sehr wohl besser ist als reines C. Dank std::string wird das string-handling wesentlich vereinfacht, durch exceptions das Fehlerhandling und Templates sorgen manchmal fuer kompakteren Code. Einziger potentieller Nachteil: std::string oder Exceptions koennen die Laufzeit meines Programmes um 2% erhoehen, bei extrem viel string-handling vllt. sogar 20-50%, aber das sind Sonderfaelle.
Zugegeben ist C++ 'ne ziemlich grosse Sprache fuer Anfaenger mit grossen Stolpersteinen. Einem Anfaenger wuerd ich auch zu mehr High-Level raten. Aber gerade wenn man Low-Level machen will und nicht durch die Umgebung auf C verwiesen ist, kann man mit C++ oft zur gleichen Performance lesbareren Code schreiben. IMHO. Man muss dann aber wissen was man tut, dazu muss man dann wohl auch den C-Teil von C++ verstehen.
FreakY<3Cpp schrieb:
Wenn C++ objektiv nicht schön ist, frag ich mich was C ist. C hat eigentlich nicht mal den Ansatz von Objektivität.
Der Unterschied zwischen "objektiv schoen" und "schoen objekt-orientiert" ist dir klar?
-
Blue-Tiger schrieb:
Reine Neugier: was waer denn ein Beispiel eines solchen Workarounds?
Na z.B. ist Exception Handling zusammen mit manueller Speicherverwaltung eine Blöde Idee, weil erzeugte Objekte nach einer Exception nicht freigegeben werden. In C++ sind daher Krücken wie RAII bzw. Smart Pointer notwendig.
Ich verweise auch mal auf http://yosefk.com/c++fqa/defective.html
Das schoene an C++ ist ja grad, dass du all die Features zur Auswahl hast, aber sie nicht benutzen musst. Ich schreibe oft und gern prozedurales C++ und wage zu behaupten dass das sehr wohl besser ist als reines C.
Naja, das ist Ansichtssache. Ich würde es als schlechten Stil empfinden, wenn man zur Lösung eines Problems nicht die von der Sprache genau dafür gedachten Features verwendet und entsprechend dem Paradigma der Sprache programmiert, sondern sich nur bestimmte Features rauspickt und sich irgendwie anders durchmogelt. Vergleichbar wäre es, wenn man in C keine Schleifen verwendet, sondern stattdessen alles mit goto macht.
Und C++ bietet jede Menge Features, die aber alle irgendwelche Probleme haben, so dass man gezwungen ist, auf andere Features auszuweichen, oder auf die Low-Level-Ebene von C. Und sowas empfinde ich nicht als schön.
Ich will, dass eine Sprache sich auf ein bestimmtes Paradigma festlegt, und mir dazu passend einen gut durchdachten, konsistenten Satz von vielseitig verwendbare Features bietet, mit dem ich jedes Problem elegant lösen kann. Das ist natürlich ein Ideal, das praktisch wohl von keiner Sprache wirklich erreicht wird, aber IMHO ist C++ am weitesten davon entfernt.
-
namespace invader schrieb:
Na z.B. ist Exception Handling zusammen mit manueller Speicherverwaltung eine Blöde Idee, weil erzeugte Objekte nach einer Exception nicht freigegeben werden. In C++ sind daher Krücken wie RAII bzw. Smart Pointer notwendig.
selbes problem hast du in jeder sprache. finally ist idr schlechter als raii.
Ich verweise auch mal auf http://yosefk.com/c++fqa/defective.html
damit disqualifizierst du dich selbst...
Naja, das ist Ansichtssache. Ich würde es als schlechten Stil empfinden, wenn man zur Lösung eines Problems nicht die von der Sprache genau dafür gedachten Features verwendet und entsprechend dem Paradigma der Sprache programmiert, sondern sich nur bestimmte Features rauspickt und sich irgendwie anders durchmogelt. Vergleichbar wäre es, wenn man in C keine Schleifen verwendet, sondern stattdessen alles mit goto macht.
dh in sprachen wie ruby ist also kein guter stil möglich?
Ich will, dass eine Sprache sich auf ein bestimmtes Paradigma festlegt, und mir dazu passend einen gut durchdachten, konsistenten Satz von vielseitig verwendbare Features bietet, mit dem ich jedes Problem elegant lösen kann. Das ist natürlich ein Ideal, das praktisch wohl von keiner Sprache wirklich erreicht wird, aber IMHO ist C++ am weitesten davon entfernt.
das ist eine schlechte idee.
weil manchmal muss man funktional, manchmal objekt orientiert und manchmal bunt arbeiten.
-
Shade Of Mine schrieb:
Ich verweise auch mal auf http://yosefk.com/c++fqa/defective.html
damit disqualifizierst du dich selbst...
Damit outest du dich als C++-Fan, der von Kritik an seiner Lieblingssprache nichts wissen will :p
Ich sehe ja ein, dass es anscheinend Leute gibt, die an dem Feature-Mischmasch in C++ gefallen finden, die sollen dann von mir aus ruhig bei C++ bleiben.
-
namespace invader schrieb:
Damit outest du dich als C++-Fan, der von Kritik an seiner Lieblingssprache nichts wissen will :p
Ich denke ich sehe C++ sehr kritisch. Aber 99% der argumente auf dieser Trollseite sind lächerlich. Interessanter ist da zB das hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-263094-and-start-is-0.html
-
sondern sich nur bestimmte Features rauspickt und sich irgendwie anders durchmogelt.
C++ ist ein Werkzeugkasten zum Loesen von Problemen (wie jede andere Sprache auch). Dazu vielleicht ein real life example: In meiner Garage sind allerhand Werkzeuge und Geraete: Sense, Schraubenzieher, Maulschluessel, Paketmesser ... Nun habe ich ein Problem: Ein Loch im Fahrradschlauch will geflickt werden. Sicher verwende ich dazu keine Sense. Habe ich jetzt gemogelt?
auf ein bestimmtes Paradigma festlegt .. mit dem ich jedes Problem elegant lösen kann.
"Dude, not every problem is an objekt" oder "There is no silver bullet". Sobald man sich festgelegt hat, gibt es Probleme, die damit nicht elegant zu loesen sind. Oder anders: Will man Probleme elegant loesen, dann darf man sich nicht auf ein Paradigma versteifen. Sei offen ..
-
namespace invader schrieb:
Na z.B. ist Exception Handling zusammen mit manueller Speicherverwaltung eine Blöde Idee, weil erzeugte Objekte nach einer Exception nicht freigegeben werden. In C++ sind daher Krücken wie RAII bzw. Smart Pointer notwendig.
RAII löst das Problem des Resourcenhandlings zuverlässig - GC nicht. Daher darf man sich in Java & Co mit finally Blöcken herumschlagen. Das empfinde ich als ineffektiv.
namespace invader schrieb:
Naja, das ist Ansichtssache. Ich würde es als schlechten Stil empfinden, wenn man zur Lösung eines Problems nicht die von der Sprache genau dafür gedachten Features verwendet und entsprechend dem Paradigma der Sprache programmiert, sondern sich nur bestimmte Features rauspickt und sich irgendwie anders durchmogelt.
C++ ist wie Ada eine Multiparadigmenprogrammiersprache und erhebt nicht den Anspruch die reine Lehre zu vertreten, sondern für den erfahrenen Programmierer meistens das effektivste Werkzeug bereitzustellen. Das bedingt eine hohe Komplexität der Sprache.
namespace invader schrieb:
Ich will, dass eine Sprache sich auf ein bestimmtes Paradigma festlegt,
Am Ende kommen ineffektive Programme dabei heraus, nicht jedes Problem läßt sich elegant mit nur einem Paradigma lösen.
-
namespace invader schrieb:
Ich will, dass eine Sprache sich auf ein bestimmtes Paradigma festlegt, und mir dazu passend einen gut durchdachten, konsistenten Satz von vielseitig verwendbare Features bietet, mit dem ich jedes Problem elegant lösen kann. Das ist natürlich ein Ideal, das praktisch wohl von keiner Sprache wirklich erreicht wird, aber IMHO ist C++ am weitesten davon entfernt.
Ja, aber gerade weil die C++-Philosophie darin besteht, sich nicht auf ein einzelnes Paradigma festzulegen. Warum auch? Die wirklichen Möglichkeiten kommen erst zum Tragen, wenn man verschiedene Konzepte kombiniert. Zum Beispiel generische mit objektorientierter Programmierung in C++. Prozedurale Anteile hat man ohnehin in sehr vielen OOP-Sprachen dabei.
Man sieht ja, wie es rauskommt, sich auf etwas zu versteifen. Früher hat z.B. Java sehr starken Wert auf OOP gelegt und versucht, alles damit zu lösen. Das Ergebnis waren Collections ohne Typsicherheit oder grosse, rigide Klassenhierarchien. Ein Teil davon ist inzwischen durch die Einführung von Generics verbessert worden.
-
namespace invader schrieb:
Shade Of Mine schrieb:
Ich verweise auch mal auf http://yosefk.com/c++fqa/defective.html
damit disqualifizierst du dich selbst...
Damit outest du dich als C++-Fan, der von Kritik an seiner Lieblingssprache nichts wissen will :p
Man muss kein ignoranter C++ fanboy sein, um diese Seite, die du gelinkt hast, schlecht zu finden. Das meiste, was dort steht, ist im besten Fall umstritten und im schlechtesten Fall einfach FUD. Kannst ja auch mal das hier lesen.
-
namespace invader schrieb:
Ich will, dass eine Sprache sich auf ein bestimmtes Paradigma festlegt,
[...]
Das ist natürlich ein Ideal, das praktisch wohl von keiner Sprache wirklich erreicht wird, aber IMHO ist C++ am weitesten davon entfernt.es gibt solche Sprachen: Forth, LISP, Haskell, Self, Smalltalk, APL ...
- die sind für gewöhnlich nur nicht so furchtbar beliebt. Dafür sind sie äußerst langlebig, weil unabhängig von Syntax-Mode-Erscheinungen etc
-
~john schrieb:
RAII löst das Problem des Resourcenhandlings zuverlässig - GC nicht. Daher darf man sich in Java & Co mit finally Blöcken herumschlagen. Das empfinde ich als ineffektiv.
Damit RAII das Problem löst, muss man aber Freigaben in Destruktoren verpacken (obwohl das in manchen Fällen gar nicht sinnvoll ist) und sich mit Smart Pointern rumschlagen (die nun wirklich ein hässlicher Workaround sind).
In Java wird das meiste Ressourcenhandling automatisch vom GC erschlagen, und für den Rest gibt es mit finally eine einfache und klare Lösung. Vor allem kann man mit finally auch für andere, die den Code später lesen, klar ausdrücken, dass dort Ressourcen freigegeben werden. Bei RAII-Frickeleien, eventuell auch mit zusätzlichen Scopes nur zu dem Zweck, ist das nicht so einfach verständlich.
Nexus schrieb:
Ja, aber gerade weil die C++-Philosophie darin besteht, sich nicht auf ein einzelnes Paradigma festzulegen. Warum auch? Die wirklichen Möglichkeiten kommen erst zum Tragen, wenn man verschiedene Konzepte kombiniert. Zum Beispiel generische mit objektorientierter Programmierung in C++. Prozedurale Anteile hat man ohnehin in sehr vielen OOP-Sprachen dabei.
Das Problem sind ja nicht die prozedualen Anteile (letztendlich ist OOP ja nur eine Erweiterung prozedualer Programmierung, also ist es keine besondere "Kombination"), sondern die aus C übernommenen Low-Level-Anteile, vor allem Zeiger die beliebig überall hin zeigen können. Die verhindern, dass man die ganzen schönen High-Level-Features unbesorgt nutzen kann; man muss immer die Low-Level-Ebene im Hinterkopf haben. C++ abstrahiert nicht davon, sondern versteckt nur ein paar Details. Also kein großer Vorteil zu C.
Ich halte es für sinnvoller, dass eine High-Level-Sprache z.b. einen Garbage Collector mitbringt, denn der ist auf dieser Ebene brauchbarer als C-Pointer.
IMHO ist C++ für eine High-Level-Sprache nicht high-level genug, für eine Low-Level-Sprache zu kompliziert und obfuskierend, und insgesamt einfach unschön, schlecht durchdacht und sicher nicht für Anfänger geeignet (darum ging es in dem Thread ja eigentlich mal).
krümelkacker schrieb:
Man muss kein ignoranter C++ fanboy sein, um diese Seite, die du gelinkt hast, schlecht zu finden.
Ich vermute doch. Wo finde ich denn Kritik an dieser Seite von Leuten, die C++ ebenso nicht sonderlich mögen?
-
Man braucht nur geplagten Java/C#-Programmierern zu sagen, daß es da eine Sprache gibt, die ohne finally/using auskommt und sie kommen.
Das Bißchen, wo man in C++ freigeben muß, muß man woanders Absonderliches machen.
-
namespace invader schrieb:
Vor allem kann man mit finally auch für andere, die den Code später lesen, klar ausdrücken, dass dort Ressourcen freigegeben werden. Bei RAII-Frickeleien, eventuell auch mit zusätzlichen Scopes nur zu dem Zweck, ist das nicht so einfach verständlich.
Du biegst gerade das Problem, dass der Programmierer Nicht-Speicher-Ressourcen explizit freigeben muss, zu einem Vorteil um. Ist es wirklich besser, wenn man an Dinge wie Freigabe der angeforderten Ressourcen ständig denken und dafür Boilerplate-Code schreiben muss, der eh immer gleich aussieht? Sowas ist nämlich eine nicht zu unterschätzende Fehlerquelle.
namespace invader schrieb:
Das Problem sind [...] die aus C übernommenen Low-Level-Anteile, vor allem Zeiger die beliebig überall hin zeigen können. Die verhindern, dass man die ganzen schönen High-Level-Features unbesorgt nutzen kann; man muss immer die Low-Level-Ebene im Hinterkopf haben. C++ abstrahiert nicht davon, sondern versteckt nur ein paar Details. Also kein großer Vorteil zu C.
Das stimmt nun aber komplett nicht. C++ abstrahiert sehr wohl von Low-Level-Features. Natürlich geschehen hinter den Fassaden immer noch Low-Level-Operationen, aber für den Benutzer ist die Schnittstelle relevant.
Mittels RAII kann man zum Beispiel sehr schön manuelle Speicheranforderung umgehen. Oder mit überladenen Funktionen wird es möglich, ähnliche Aktionen gleich anzusprechen. Oder mit Templates erreicht man Typsicherheit und kann auf
void*
verzichten. Oder mit Laufzeitpolymorphie hat man implizite Type-Switches. Oder mit Operatorüberladung kann man benutzerdefinierte Typen analog zu BuiltIns verwenden.Was daran ist für dich keine Abstraktion?
namespace invader schrieb:
Ich halte es für sinnvoller, dass eine High-Level-Sprache z.b. einen Garbage Collector mitbringt, denn der ist auf dieser Ebene brauchbarer als C-Pointer.
Das sehen eben viele Leute anders. Ein GC hat auch Probleme, weil er keine deterministische Zerstörung garantiert. Oder weil man nicht weiss, wann er zum Zug kommt. Das sind alles Faktoren, die entscheidend sein können. Ich persönlich bin froh, hat C++ keinen GC. Und dennoch frickle ich nicht dauernd mit
new
unddelete
herum.
-
namespace invader schrieb:
Damit RAII das Problem löst, muss man aber Freigaben in Destruktoren verpacken (obwohl das in manchen Fällen gar nicht sinnvoll ist) und sich mit Smart Pointern rumschlagen (die nun wirklich ein hässlicher Workaround sind).
In Java wird das meiste Ressourcenhandling automatisch vom GC erschlagen, und für den Rest gibt es mit finally eine einfache und klare Lösung. Vor allem kann man mit finally auch für andere, die den Code später lesen, klar ausdrücken, dass dort Ressourcen freigegeben werden. Bei RAII-Frickeleien, eventuell auch mit zusätzlichen Scopes nur zu dem Zweck, ist das nicht so einfach verständlich.
Wie wir alle nicht das gute alte
finally { if(o!=null) { try { o.close(); } catch(Exception e) {} }
lieben...
RAII ist um laengen besser als finally. ein gc ist natuerlich auch super aber gc und raii sind keine sich widersprechenden konzepte. raii ist fuer jede art von resource gut, ein gc nur fuer rohen speicher.
ideal ist natuerlich ein gc und raii. nicht umsonst wird der GC in einigen Sprachen wie zB python oder C# durch eine schwache form von RAII unterstuetzt: dem konzept von "using". wo eine resource temporaer zu einem raii objekt gemacht werden kann.
krümelkacker schrieb:
Man muss kein ignoranter C++ fanboy sein, um diese Seite, die du gelinkt hast, schlecht zu finden.
Ich vermute doch. Wo finde ich denn Kritik an dieser Seite von Leuten, die C++ ebenso nicht sonderlich mögen?
Das macht keinen Sinn.
Warum sollte jemand der C++ nicht mag eine Seite kritisieren die C++ kritisiert? Genausowenig wirst du Kritik an Java Kritik von Java Kritikern finden.Lies mal zB comp.lang.c++.moderated oder so, dort sind wohl alle Punkte dieser troll-seite widerlegt worden. Natuerlich ist eine gewisse Kritik ja durchaus berechtigt. C++ hat eine Menge sachen die nicht ideal sind, Imperfect C++ ist zB ein gutes Buch dazu. Aber das meiste was man so liest ist eben nur getrolle.
-
Shade Of Mine schrieb:
Wie wir alle nicht das gute alte
finally { if(o!=null) { try { o.close(); } catch(Exception e) {} }
lieben...
Ein reines Syntax-Problem:
with open("in.txt") as infile: print(infile.read())
Wie heisst die Sprache?
-
mngbd schrieb:
Shade Of Mine schrieb:
Wie wir alle nicht das gute alte
finally { if(o!=null) { try { o.close(); } catch(Exception e) {} }
lieben...
Ein reines Syntax-Problem:
with open("in.txt") as infile: print(infile.read())
Wie heisst die Sprache?
Das war ein häßlichkeits-Beispiel aus der Java-Welt.
Nachdem du deinen Dateilese/schreibekram erledigt hast, musst du die Datei noch schließen (auch wenn ein Lese/Schreibfehler auftrat, deswegen im finally-Block). Aber erst einmal prüfen, ob es das Objekt überhaupt gibt (kann ja schon bei der Erzeugung eine Exception aufgetreten sein), dann musst du die Datei schließen - was ja auch eine Exception werfen kann, deswegen nochmal Block drum rum.