Warum programmieren einige noch in C?
-
@Computerwelt
Der allgemeine Konsens ist schon seit > 20 Jahren dass Implementierungs-Vererbung böse ist und eher vermieden werden sollte. Dass du sowas grauenhaft findest kann ich gut nachvollziehen.Nur hat das IMO nicht sehr viel mit OOP zu tun. Man kann jedes Werkzeug misbrauchen, und mit Vererbung ist das nicht anders. Wenn jetzt jemand glaubt OOP würde irgendeine Empfehlung enthalten alles wo es irgendwie geht über Implementierungs-Vererbung zu machen, dann halte ich es nur für vernünftig dass er OOP ableht. Nur gleichzeitig meine ich auch dass sein Verständnis des Begriffs OOP ... seltsam/unüblich und problematisch ist.
-
@hustbaer sagte in Warum programmieren einige noch in C?:
@It0101 Ach wir streiten uns doch gerade mal so ein bisschen. Ich glaube dass @Bashar irgendwas hier ziemlich aufgeregt hat und er das morgen/in ein paar Tagen viel entspannter sehen wird.
Aber ausgerechnet im C-Unterforum.... das ist als würden die Eltern zum Streiten in die verwahrloste Messy-Wohnung nebenan gehen....
-
@5cript
OK. Ich habe genügend schrecklichen C Code und schrecklichen C++ Code gesehenWas das Verwenden von C Libraries angeht: das ist oft relativ einfach. Zumindest wenn man sich über bestimmte Dinge keine Gedanken macht. Wie z.B. thread-safety oder wie man das Ding in einem Programm mit dynamisch nachgeladenen Modulen sauber verwenden kann.
Das Verwenden von vielen C++ Libraries ist aber auch ausreichend einfach. Zumindest wenn man gut C++ kann. Und wenn man nicht ganz so gut C++ kann, ist der Vergleich IMO nicht ganz sinnvoll. Denn dann ist das eigentliche Thema dass C++ komplexer und schwieriger zu erlernen ist als C -- und nicht was man damit (und den in der Sprache verfügbaren Libraries) anfangen kann wenn man es erstmal beherrscht.
Mir ging es aber auch eher um Programme die in C entwickelt sind, bzw. bei Libraries nicht um die Verwendung der Library sondern darum wenn man sie modifizieren/erweitern möchte. Und da sehe ich einfach verdammt oft grässliche Dinge. (Was bei Programmen bzw. Libraries die in C++ entwickelt sind nicht unbedingt viel besser ist, aber das ist wieder ein anderes Thema.)
-
@It0101 sagte in Warum programmieren einige noch in C?:
Aber ausgerechnet im C-Unterforum.... das ist als würden die Eltern zum Streiten in die verwahrloste Messy-Wohnung nebenan gehen....
Wobei der Punkt ja gerade ist, dass man in jeder Sprache guten oder schlechten Code schreiben kann. Gutes C anzusehen ist genauso eine Freude an Klarheit und Logik wie bei jeder anderen Sprache. Nur leider wird in vielen Lehrbüchern eine Art halbgares Fortran60 mit C-Syntax gelehrt. Und viele C++ Bücher verleiten dazu, überkomplexe Sprachmittel rücksichtslos einzusetzen. Ein Jürgen Wolf schreibt eben in jeder Sprache unverständlichen Code.
Ich empfehle das Kapitel in K&R, wo sie die
string.h
herleiten. Da kann man schön sehen, wie man in C sauber und methodisch entwickelt.Die string.h ist übrigens auch ein relativ objektorientierter Teil der C-Library. Das Konzept der Nullterminierung ist eine interne Invariante der "Klasse", die innerhalb der Funktionen aufrechterhalten wird und nicht nach außen dringt. Ok, kaum nach außen dringt, denn leider fehlt hier als wesentlicher Teil eine Art Konstruktor, wodurch es dem Anwender überlassen ist, passend großen Platz zu besorgen und dieses Implementierungsdetails zu kennen. Das hätte man besser machen können, ging aber vermutlich durch Anforderungen an Stringliterale nicht.
-
@hustbaer sagte in Warum programmieren einige noch in C?:
@Bashar sagte in Warum programmieren einige noch in C?:
@hustbaer Es ist absolut irre zu behaupten, eine Bibliothek, die in den 70ern für C designt wurde, sei eindeutig mustergültiges OOP.
Mehrere Probleme mit dieser Aussage.
- Nur dass etwas zu einer bestimmten Zeit entworfen wurde, heisst nicht, dass es nicht einem Konzept entsprechen kann das zu einer anderen Zeit formuliert wurde. Würde man irgendwo ein 1 Mio. altes Rad finden, wäre es immer noch ein Rad. Wobei ich nicht weiss wann der Begriff geprägt wurde, aber der Knackpunkt ist ja gerade: es spielt keine Rolle. Weiters sollte wohl klar sein dass die meisten Konzepte der Softwareentwicklung die einen Namen haben, diesen erst bekommen haben nachdem sie bereits angewendet wurden.
Das ist eine Meinung, die ich akzeptieren kann. Ich stimme mit ihr nicht überein und finde den Vergleich mit dem Rad nicht ganz passend, aber was solls.
- Ich habe nie behaupte dass es mustergültiges OOP ist. Das ist ein Strohmann. Ich behaupte weder dass es mustergültiges OOP ist noch dass es nicht mustergültiges OOP is. Nur dass es meiner Meinung nach ganz klar als OOP einzustufen ist.
- Niemand hat (hier) behauptet dass die ganze C Standard Library objektorientiert ist, denn das ist sie ganz klar nicht. Es wurde ein konkretes Beispiel genannt, und zwar die FILE* API die ein Teil der Standard Library ist. Wieder ein Strohmann.
Du nicht, aber SeppJ. Siehe weiter oben. Da du dich in den Thread völlig unsachlich und nur Zusammenhalt mit ihm demonstrierend eingemischt hast, musst du damit klarkommen, dass ich seine Aussage erstmal auch dir zurechne.
Wieso muss ich das widerlegen? Wer die irren Behauptungen aufstellt, muss Beweise führen.
Der wichtigste Punkt der objektorientierten Programmierung ist dass man Daten und den Code der mit diesen Daten arbeitet zusammenfasst. Ein weiterer wichtiger Punkt dabei ist die Kapselung, also dass man diese Daten davor schützt anderweitig modifiziert zu werden. Die Kombination aus Daten und Code ist das Objekt. Die FILE* API erfüllt das. Die FILE* API ermöglicht dir mit FILE Objekten zu arbeiten. Die FILE* API ist objektorientiert.
Done.
Wenn sie echt objektorientiert wäre -- also von jemandem entworfen, der von OOP schonmal was gehört hat --, könnte man z.B. eigene Streamtypen definieren und mit der API verwenden. Dann würde es Stringstreams geben, und später hätte jemand Netzwerkstreams dazupacken können. Man hätte die Verantwortlichkeiten getrennt, IO hier, Buffering da.
Alles was hier von OOP übrig ist, ist die Kapselung. Das hat man vorher schon gekannt, und das ist ja auch für sich schon ein sinnvolles Konzept.
Mir ist hier vor allem eure Motivation unklar. In den 90ern gab es wie gesagt diesen Hype, da musste alles objektorientiert sein, was nicht bei Drei auf den Bäumen war. Aber heute? Was soll das denn?
Datei-IO in Haskell funktioniert auch so, dass man ein undurchsichtiges Handle bekommt und da irgendwelche Funktionen drauf anwendet, ist das jetzt auch ein mustergültiges Beispiel für Objektorientierung? Was muss man denn tun, um nicht objektorientiert zu sein?
Davon abgesehen ist sowohl die Behauptung dass etwas einem Konzept entspricht als auch die Behauptung dass es ganz klar nicht diesem Konzept entspricht etwas womit du dir einen "burden of proof" einhandelst.
Ich betreibe hier keine formale Debatte, und ich bin auch nicht daran interessiert, zu gewinnen. Was soll das sein, krieg ich dann ein paar Reputationspunkte oder mehr Follower? Mir egal, dafür nehme ich mir das Recht heraus, Diskussionen zu verweigern, die ich für blödsinnig halte. Ich mach das hier nur, weil ich von dir recht viel halte und herausfinden möchte, ob wir echt fundamental unterschiedliche Meinungen haben oder ob es nur so scheint.
Wo kommt denn der ganze OOP-Hype der 80er/90er/2000er her? Wieso hat Bjarne Stroustrup C++ entwickelt? Wieso gibt es Objective-C, wieso gibt es Java? Doch wohl kaum, weil OOP mit C damals schon ein alter Hut war.
Niemand hat behauptet dass C objektorientierte Programmierung besonders einfach macht
Ähm, doch? Hast du den Thread überhaupt gelesen?
Ihr könnt doch bestenfalls argumentieren, dass OOP, aus einer gewissen Perspektive gesehen, im Prinzip schon in C existiert. Und müsst euch dann auf die Entgegnung, wo denn die Vererbung und Polymorphie bleiben, etwas einfallen lassen, um das zu relativieren.
Nicht wirklich. Guck dir COM an. Das ist OOP mit Vererbung und Polymorphie.
COM ist vor allem eine Krankheit.
Wenn du den Thread gelesen hättest, hättest du auch das gelesen:
ich:
OOP kann man irgendwie hinhacken, siehe GTK und endlose Diskussionen hier, und ob das "sehr gut" ist, ist am Ende ja offenbar Geschmackssache.
Ich hab ja nicht gesagt, dass es nicht geht. Notfalls benutzt man Cfront
jetzt wieder du:
Und sogar FILE* ist polymorph. Ob jetzt dadurch dass ein Kernel drunter sitzt der Files, serielle Schnittstellen und andere Geräte hinter einer ebenso polymprohen C API versteckt oder nicht ist dabei auch wurscht. Denn wäre dieser Kernel nicht da könnte man die selbe Polymorphie auch direkt in der Standard Library erreichen.
Das meine ich mit "relativieren". Man biegt sich alles irgendwie zurecht.
Davon abgesehen halte ich gerade Vererbung (abgesehen von reiner Interface-Vererbung) für eher problematisch und etwas was mit dem modernen Verständnis von OOP nicht viel zu tun hat.
Das ist nicht das Thema. Ich selbst stehe ja OOP an sich kritisch gegenüber. Hier gehts um was OOP ist, nicht darum, was gut ist.
Mit dem zum Idioten erklären hast denke ich du angefangen. Ebenso bist du es der damit angefangen hat dogmatisch auf einer Meinung zu beharren und sich gleichzeitig zu weigern das Thema überhaupt zu diskutieren. Oder auch nur zu erklären wie seine Meinung überhaupt genau aussieht.
Das hat sich wohl so hochgeschaukelt.
-
@Bashar sagte in Warum programmieren einige noch in C?:
- Ich habe nie behaupte dass es mustergültiges OOP ist. Das ist ein Strohmann. Ich behaupte weder dass es mustergültiges OOP ist noch dass es nicht mustergültiges OOP is. Nur dass es meiner Meinung nach ganz klar als OOP einzustufen ist.
- Niemand hat (hier) behauptet dass die ganze C Standard Library objektorientiert ist, denn das ist sie ganz klar nicht. Es wurde ein konkretes Beispiel genannt, und zwar die FILE* API die ein Teil der Standard Library ist. Wieder ein Strohmann.
Du nicht, aber SeppJ. Siehe weiter oben. Da du dich in den Thread völlig unsachlich und nur Zusammenhalt mit ihm demonstrierend eingemischt hast, musst du damit klarkommen, dass ich seine Aussage erstmal auch dir zurechne.
Deine Antwort passt auf Punkt 2 aber nicht auf Punkt 3. Egal. z.T. unsachlich: ja, meine Erwiderung auf deinen sehr unsachlichen Beitrag war sehr unsachlich. (Mit voller Absicht übrigens.)
Wenn sie echt objektorientiert wäre -- also von jemandem entworfen, der von OOP schonmal was gehört hat --,
Du vermischt gerade Intention und Ergebnis. Die einer Sache innewohnenden Eigenschaften sind unabhängig davon wie die Sache entstanden ist. Und die ihr bloss zugeordneten/zugesprochenen Eigenschaften (wie z.B. wer eine Sache hergestellt hat oder in welchem Geiste sie hergestellt wurde), sind etwas was mich eher weniger interessiert. Ganz allgemein, und erst recht wenn es um Softwareentwicklung geht.
BTW: Anscheinend gibt es den Begriff "object oriented" schon seit den späten 50er/frühen 60er Jahren. (Weil du vorhin schriebst (sinngemäss) es wäre irre anzunehmen etwas aus den 70ern könne objektorientiert sein...)
könnte man z.B. eigene Streamtypen definieren und mit der API verwenden.
Ähm. Das könnte man dann vielleicht, aber nicht notwendigerweise. Und Gründe etwas nicht polyporph bzw. nicht erweiterbar polymorph zu machen gibt es mMn. viele. KISS, Performance, Implementierungsoverhead und dass es verdammt schwer ist nicht-triviale APIs sauber erweiterbar polymorph zu machen.
Wenn "erweiterbar polyporph" für dich ein absolut notwendiges Kriterium für OOP ist, dann passt das natürlich nicht zu FILE*. Für mein Verständnis von OOP ist es kein notwendiges Kriterium.
Ich betreibe hier keine formale Debatte, und ich bin auch nicht daran interessiert, zu gewinnen. Was soll das sein, krieg ich dann ein paar Reputationspunkte oder mehr Follower?
Das war meine Antwort auf
Wieso muss ich das widerlegen? Wer die irren Behauptungen aufstellt, muss Beweise führen.
Ich wollte darauf hinaus dass die Aussage "wer die (irre) Behauptungen aufstellt, muss Beweise führen" auch genau so für dich gilt, da du ebenso (irre) Behauptungen aufstellt hast.
Niemand hat behauptet dass C objektorientierte Programmierung besonders einfach macht
Ähm, doch? Hast du den Thread überhaupt gelesen?
Ja, doch. Muss mir aber entgangen sein. Wo? Wer?
Das meine ich mit "relativieren". Man biegt sich alles irgendwie zurecht.
Nein, ich biege mir nichts zurecht. Meine Definition des Begriffs OOP erfordert kein zurechtbiegen damit FILE* objektorientiert ist. Die wesentlichen Dinge sind erfüllt, und damit is es für mich objektorientiert.
Ich habe irgendwie den Eindruck dass du siehst OOP als eine Art Religion oder noch schlimmer: Kirche. Für mich ist das einfach nur ein Konzept bzw. eine lose Ansammlung von Konzepten, wovon manche wichtiger sind und manche weniger wichtig.
Wenn du es nicht objektorientiert nennen willst... wie nennst du dann das was heute in sinnvoll und gut entworfenen C, C++ oder C# Programmen gemacht wird wo mit sauber gekapselten Objekten gearbeitet wird, erweiterbare oder geschlossene Polymorphie dort und nur dort eingesetzt wird wo sie Sinn macht etc.?
-
@SeppJ sagte in Warum programmieren einige noch in C?:
Was würdest du denn als wesentliche Eigenschaft von OOP sehen, das von FILE nicht erfüllt wird? Du sagst als einziges, dass es 'alt' wäre, aber das kann's ja wohl kaum sein.
In der Ursprungsversion war das einfach eine Datenstruktur mit opaken Zeiger (f* Funktionen) bzw. Nummer für das entsprechende Handel im Kernel und dazu passenden Funktionen – mehr nicht. Dazu leistet das OOP nicht die C Library sondern der darunter liegende Kernel. Die C Library schreibt bei einem
write
Daten nur in einen Puffer (der sieht für sie immer gleich aus, d.h. sie hat keinerlei Ahnung um was für ein Device es sich handelt), um den Rest u.a. wie das konkret auf das spezielle Device geschrieben werden muss kümmert sich der Kernel. D.h. alles was OOP ist, spielt sich im Kernel ab nicht in der C Library.Es gibt keinerlei API Schnittstelle in der C Library wie man das erweitern könnte. Bei Xt existiert das.
-
Also kann man in C++ auch schön programmieren ohne den Zwang zu unterliegen aus allem gleich ein Objekt machen zu müssen?
-
@Computerwelt sagte in Warum programmieren einige noch in C?:
Also kann man in C++ auch schön programmieren ohne den Zwang zu unterliegen aus allem gleich ein Objekt machen zu müssen?
Du kannst ja das C von C++ benutzen
-
@hustbaer sagte in Warum programmieren einige noch in C?:
Wenn sie echt objektorientiert wäre -- also von jemandem entworfen, der von OOP schonmal was gehört hat --,
Du vermischt gerade Intention und Ergebnis.
OOP ist eine spezifische Entwurfs/Programmiermethode. Man kann etwas OOP nennen, wenn es dieser Methode entspricht. Das kann theoretisch zufällig passieren, aber dann muss es eben so aussehen als ob der Autor diese Methode befolgt hat.
BTW: Anscheinend gibt es den Begriff "object oriented" schon seit den späten 50er/frühen 60er Jahren. (Weil du vorhin schriebst (sinngemäss) es wäre irre anzunehmen etwas aus den 70ern könne objektorientiert sein...)
Und was ist damit gemeint? Es ist ja nicht sehr fernliegend, sich irgendwie an Objekten zu orientieren.
könnte man z.B. eigene Streamtypen definieren und mit der API verwenden.
Ähm. Das könnte man dann vielleicht, aber nicht notwendigerweise. Und Gründe etwas nicht polyporph bzw. nicht erweiterbar polymorph zu machen gibt es mMn. viele. KISS, Performance, Implementierungsoverhead und dass es verdammt schwer ist nicht-triviale APIs sauber erweiterbar polymorph zu machen.
Für meine Begriffe sagst du damit, es gab gute Gründe, diese API nicht objektorientiert zu machen. Die Gründe lagen praktisch darin, dass C das nicht so einfach ermöglicht und dass die Entwickler das auch gar nicht im Sinn hatten, das zwar am Rande, aber es sollte auch nicht in Vergessenheit geraten.
Ich wollte darauf hinaus dass die Aussage "wer die (irre) Behauptungen aufstellt, muss Beweise führen" auch genau so für dich gilt, da du ebenso (irre) Behauptungen aufstellt hast.
Aus meiner Sicht nicht. Ich stehe auf dem Standpunkt, das ich lediglich die Mainstream-Sichtweise, was OOP ist, wiedergebe. Und ihr euch aus nicht nachvollziehbaren Gründen für eine Definition entschieden habt, die so umfassend ist, dass sie aus meiner Sicht schon fast bedeutungslos ist. Ich muss mich nicht dafür rechtfertigen, dass ich genausogut Wikipedia oder irgendein relevantes Buch aus dem Regal nehmen und die Einführung zitieren könnte. Ihr müsst das, wenn ihr Entwürfe, die vor der OOP-Ära entstanden sind, als "mustergültige OOP" bezeichnet.
Niemand hat behauptet dass C objektorientierte Programmierung besonders einfach macht
Ähm, doch? Hast du den Thread überhaupt gelesen?
Ja, doch. Muss mir aber entgangen sein. Wo? Wer?
Wutz hat behauptet, OOP in C sei "sehr gut" machbar.
Ich habe irgendwie den Eindruck dass du siehst OOP als eine Art Religion oder noch schlimmer: Kirche. Für mich ist das einfach nur ein Konzept bzw. eine lose Ansammlung von Konzepten, wovon manche wichtiger sind und manche weniger wichtig.
Naja, da muss man schon trennen. OOP ist erstmal eine Idee. Für mich ist die Grundidee die von Alan Kay, aber auch nur weil ich Simula nicht kenne. Dann ist es die Geschichte dieser Idee ... C++, Objective-C, Java, UML, Design Patterns, SOLID etc.
Daraus wurde aber irgendwann eine Ideologie, nämlich in dem Moment, an dem "das ist aber nicht objektorientiert" für sich genommen schon zu einer validen Kritik wurde. Es wurde nicht mehr nachgedacht, sondern jedem Anfänger wurde eingebleut, irgendwelche "Klassen"
Person
mitgetAge
undsetName
usw. zu schreiben. Man hat erstmal irgendwelche Begriffshierarchien analysiert und dann mit Vererbungshierarchien nachgebildet. Es gab ein Heilsversprechen, und das ist der Punkt an dem man es vielleicht auch Religion nennen kann: Halte dich an diese Vorgehensweise, auch wenn es sinnlos erscheint, die Belohnung zeigt sich erst sehr viel später in richtig großen Projekten. Es gab die Idee, dass im Prinzip alle objektorientierten Programmiersprachen gleich sind, dass man einen objektorientierten Entwurf abstrakt am Whiteboard (oder UML-Tool) durchführen und dann mechanisch in Code umsetzen kann.Die Ideen haben sich in der Zwischenzeit natürlich gewandelt, das ist schon seit einiger Zeit nicht mehr so, insbesondere Vererbungshierarchien sind in Ungnade gefallen, seit man angefangen hat, mehr über Kopplung und Kohäsion nachzudenken.
So eine Ideologie ist aber auch unausweichlich. Jedes Paradigma macht manche Dinge leichter und manche schwerer als andere Paradigmen, so dass es eine Rechtfertigung erfordert, sich dem zu unterwerfen. Der eine mag seine dynamisch typisierte Sprache und nimmt Typfehler zur Laufzeit in Kauf, für den anderen ist das der Horror und er bevorzugt Sprachen mit starkem Typsystem. Ich hab trotzdem das Gefühl, dass das bei der OOP nochmal eine gesteigerte Dynamik angenommen hat.
Ich lege diese "Kirche" aber nicht als Definition für OOP zugrunde, wie du behauptest. Was bleibt ist, dass OOP eine spezifische Idee ist. In C++ gehört dazu z.B. die Verwendung von Laufzeitpolymorphie. Oft kann man ja ein bestimmtes Problem auf verschiedene Arten lösen. Wenn ich das mithilfe von OOP löse, werde ich vermutlich einige Klassen schreiben, ich werde virtuelle Funktionen anwenden. Ich kann es aber auch anders lösen. OOP ist somit ein Werkzeug, das ich anwende, wenn es passt.
Es kann auch sein, dass das Problem so simpel ist, dass sich spezifische OOP-Techniken einfach nicht anbietet. Dann halte ich es für überkandidelt, das OOP zu nennen.
Wenn du es nicht objektorientiert nennen willst... wie nennst du dann das was heute in sinnvoll und gut entworfenen C, C++ oder C# Programmen gemacht wird wo mit sauber gekapselten Objekten gearbeitet wird, erweiterbare oder geschlossene Polymorphie dort und nur dort eingesetzt wird wo sie Sinn macht etc.?
Willst du sagen, dass C, C++ und C#-Programme heute mit derselben Methodik entworfen werden? Warum sollte es dafür einen gemeinsamen Namen geben?
Was macht es für einen Sinn, jeglichen guten, modernen, übersichtlichen Programmentwurf objektorientiert zu nennen?
Vielleicht noch ein abschließender Gedanke. Ich denke, dass wir im Wesentlichen übereinstimmen. Ihr behauptet nicht, dass in C OOP (wie ich es verstehe) "sehr gut" machbar ist, oder dass die C-Standardlibrary ein "Musterbeispiel" von OOP (wie ich es verstehe) ist. Ihr habt genau die gleichen Bauchschmerzen mit OOP (wie ich es verstehe) wie ich. Der Unterschied ist, dass ihr diese Schmerzen vermeidet, indem ihr die Definition von OOP abschwächt, während ich sage: Das ist dann eben nicht OOP, so what?
-
@Bashar sagte in Warum programmieren einige noch in C?:
Daraus wurde aber irgendwann eine Ideologie, nämlich in dem Moment, an dem "das ist aber nicht objektorientiert" für sich genommen schon zu einer validen Kritik wurde. Es wurde nicht mehr nachgedacht, sondern jedem Anfänger wurde eingebleut, irgendwelche "Klassen" Person mit getAge und setName usw. zu schreiben.
Genau so etwas finde ich schrecklich.
-
@Computerwelt sagte in Warum programmieren einige noch in C?:
@Bashar sagte in Warum programmieren einige noch in C?:
Daraus wurde aber irgendwann eine Ideologie, nämlich in dem Moment, an dem "das ist aber nicht objektorientiert" für sich genommen schon zu einer validen Kritik wurde. Es wurde nicht mehr nachgedacht, sondern jedem Anfänger wurde eingebleut, irgendwelche "Klassen" Person mit getAge und setName usw. zu schreiben.
Genau so etwas finde ich schrecklich.
Und was genau stört dich? Auch in C würde ich erstmal erwarten, dass Person(en) in einer struct dargestellt werden.
Getter/setter kann man ja gerne ablehnen, aber ansonsten würden sich das C und C++ Design einer Person wohl kaum unterscheiden (ausser natürlich das ich in C z.B. keine string-Klasse habe und mich mit ekeligen char-arrays rum ärgern muss)
-
@Bashar sagte in Warum programmieren einige noch in C?:
Vielleicht noch ein abschließender Gedanke. Ich denke, dass wir im Wesentlichen übereinstimmen. Ihr behauptet nicht, dass in C OOP (wie ich es verstehe) "sehr gut" machbar ist, oder dass die C-Standardlibrary ein "Musterbeispiel" von OOP (wie ich es verstehe) ist. Ihr habt genau die gleichen Bauchschmerzen mit OOP (wie ich es verstehe) wie ich.
Das wird wohl stimmen, ja.
Der Unterschied ist, dass ihr diese Schmerzen vermeidet, indem ihr die Definition von OOP abschwächt, während ich sage: Das ist dann eben nicht OOP, so what?
Diese Formulierung impliziert/unterstellt dass wir wüssten was die "eigentliche" Definition von OOP wäre, und diese dann abschwächen. Das ist nicht so. Objektorientiert bzw. objektorientierte Programmierung heisst für mich primär dass man Code und Daten in "Objekte" zusammenfasst. Alles weitere kann man machen, muss man aber nicht. Das ist meine primäre Definition, nicht eine abgeschwächte um irgend welche Probleme zu vermeiden.
Und was das Problem dabei ist das nicht OOP zu nennen? Ganz einfach: du schreibst ein Programm das Objekte verwendest, und sagst dass es nicht objektorientiert ist. Das macht doch keinen Sinn.
-
In C kann man doch sehr wohl objekt orientiert arbeiten, eine Struct mit Funktionen, die diese bearbeiten, ist doch bereits ein Objekt. Wenn eine neue Struct die alte mit drin hat und erweitert, dann ist das eine Vererbung.
@Jockelx sagte in Warum programmieren einige noch in C?:@Computerwelt sagte in Warum programmieren einige noch in C?:
@Bashar sagte in Warum programmieren einige noch in C?:
Daraus wurde aber irgendwann eine Ideologie, nämlich in dem Moment, an dem "das ist aber nicht objektorientiert" für sich genommen schon zu einer validen Kritik wurde. Es wurde nicht mehr nachgedacht, sondern jedem Anfänger wurde eingebleut, irgendwelche "Klassen" Person mit getAge und setName usw. zu schreiben.
Genau so etwas finde ich schrecklich.
Und was genau stört dich? Auch in C würde ich erstmal erwarten, dass Person(en) in einer struct dargestellt werden.
Getter/setter kann man ja gerne ablehnen, aber ansonsten würden sich das C und C++ Design einer Person wohl kaum unterscheiden (ausser natürlich das ich in C z.B. keine string-Klasse habe und mich mit ekeligen char-arrays rum ärgern muss)Mich stört es dass bei jedem Furz gleich Getter Setter genommen werden. Durch eine Struct eine Zugehörigkeit zu pflegen, finde ich hingegen gut. Schön wären in C Namensräume, warum gibt es die nicht?
-
@Computerwelt sagte in Warum programmieren einige noch in C?:
Wenn eine neue Struct die alte mit drin hat und erweitert, dann ist das eine Vererbung.
Gefährliche Aussage, da die C Vererbung nur dann funktioniert wenn die vererbte Klasse an der ersten Stelle im Struct steht. Ansonsten fängt man sich einen bitterbösen Fehler ein. Ein Beispiel:
#include <stdio.h> typedef struct CartesianCoord { double x; double y; double z; }; typedef struct PointWrong { char Name[256]; CartesianCoord Base; unsigned long ID; }; typedef struct PointCorrect { // Hier nichts einfügen, da wir uns sonst einen gewaltigen Fehler einfangen. CartesianCoord Base; char Name[256]; unsigned long ID; }; void Init_CartesianCoord(CartesianCoord* c) { c->x = 1; // nur ein Beispiel c->y = 2; c->z = 3; } void Init_PointWrong(PointWrong* p) { p->Name[0] = 0; Init_CartesianCoord((CartesianCoord*) p); p->ID = 1; } void Init_PointCorrect(PointCorrect* p) { p->Name[0] = 0; Init_CartesianCoord((CartesianCoord*) p); p->ID = 1; } int main(int argc, char **argv) { PointWrong p; PointCorrect p2; Init_PointWrong(&p); printf("x=%f\ty=%f\tz=%f\tName=%s\tID=%lu\n", p.Base.x, p.Base.y, p.Base.z, p.Name, p.ID); Init_PointCorrect(&p2); printf("x=%f\ty=%f\tz=%f\tName=%s\tID=%lu\n", p2.Base.x, p2.Base.y, p2.Base.z, p2.Name, p2.ID); return 0; }
Als Ausgabe bekomme ich:
x=0.000000 y=0.000000 z=0.000000 Name= ID=1 x=1.000000 y=2.000000 z=3.000000 Name= ID=1
Natürlich könnte man auch die Init Funktion folgendermaßen aufrufen:
Init_CartesianCoord(&p->Base);
Aber ich glaube einige Leute würden das dann als Aggregation ansehen und die nächste Diskussionrunde würde losbrechen.
-
@Computerwelt sagte in Warum programmieren einige noch in C?:
Mich stört es dass bei jedem Furz gleich Getter Setter genommen werden.
Auch Setter und Getter sollte man "bewusst" einsetzen. Ich mag das auch nicht, wenn ganzen Klassen mit denen vollgeschissen sind. Meist gibt es Alternativen, die genauso sicher sind und trotzdem elegant sind.
Ich befülle Klassen auch gerne mal über sowas:
void loadFromFile(...); void loadFromOtherData( const OtherData & ); void parseString( const std::string & ); void loadFromXML( const XMLNode & );
Je nach Anwendungsfall findet man da durchaus Möglichkeiten, um sowas wie das hier zu vermeiden:
MyObject.setMemberA(... ); MyObject.setMemberB(... ); MyObject.setMemberC(... ); MyObject.setMemberD(... ); MyObject.setMemberE(... );
C++ bietet mehr als genug Möglichkeiten, um Dinge auch elegant zu lösen. Man muss nur drauf kommen
Was im allgemeinen aber keine Lösung ist: Alles public machen.
Funktionieren wird das schon, aber gerade bei größeren Projekten, mit mehreren Entwicklern, entsteht da schnell Schlamperei, weil dann kreuz und quer die Member verändert werden.
-
Was im allgemeinen aber keine Lösung ist: Alles public machen.
Im allgemeinen: ja. Aber das wird halt auch gerne falsch verstanden bzw. übertrieben. Was dann eben zu diesen lustigen "getter und setter für alles" Klassen führt*. Sowas sollte man dann lieber gleich als nackte struct machen.
Und es gibt schon Fälle wo nackte structs Sinn machen. z.B. wenn ich Daten erstmal unvalidiert aus einem File oder auch von einem Netzwer-Stream lesen will, dann macht es keinen Sinn
class
zu schreiben und für jedes Feld einen Getter und Setter anzubieten.Bei sowas will ich direkt beim Deserialisieren eher keine Validierung die über die Regeln des Serialisierungsprotokolls hinausgeht. Das will ich dann nachher machen. Einmal um unterscheiden zu können ob der Datenstrom einfach komplett hin ist oder ob inkonsistende Daten korrekt serialisiert wurden. Und dann ist es auch manchmal hilfreich wenn man das komplette Datenpaket bei einem Validierungsfehler schon deserialisert hat und es z.B. in lesbarer Form in ein Logfile schreiben kann.
Oder, ganz extremes Beispiel: Eine Vector3D Klasse muss nun wirklich keine getX/setX, getY/setY, getZ/setZ Funktionen haben. Das darf ruhig (bzw. sollte sogar IMO) einfach public sein.
*: Das ist natürlich nur ein Weg wie es zu den "getter und setter für alles" Klassen kommt. Natürlich gibt es auch Leute die das ganze überhaupt nicht verstanden haben und auch "getter und setter für alles" Klassen in Fällen machen wollen wo Kapselung sinnvoll ist und es sehrwohl Invarianten aufrecht zu erhalten gibt.
-
@hustbaer sagte in Warum programmieren einige noch in C?:
Und es gibt schon Fälle wo nackte structs Sinn machen
Es ist auch sehr gut zu lesen, wenn man sich an die Konvention hält, dass in structs alles public ist.
Dann drückt das eine Menge aus, wenn jemand ein struct verwendet.
-
@hustbaer
Das was du beschreibst sind auch ungefähr die Ausnahmefälle, die mir so in den Sinn kamen. Wenn ich z.B. ein Message-Format habe, welches immer 10 Byte Header hat, dann ist so ein struct in das ich einfach 10 Byte reinkopiere aus meiner Sicht die bessere Wahl, im Vergleich zum einzelnen parsen und setzen der Werte in einer Klasse. ( unter Beachtung des data structure alignments natürlich ).
-
Gibt es denn eigentlich Bücher in denen schönes C++ gelehrt wird? Die meiste Fachliteratur schreibt nur alle Möglichkeiten runter, aber was davon best practice ist und was man lieber lässt, erfährt man nicht.