C auch OOP?
-
Tachyon schrieb:
OOP ist mit C nicht möglich. Punkt. Was man in C, und eigentlich so gut wie mit jeder imperativen Sprache machen kann, ist OBP.
Konzepte wie Polymorphie oder Vererbung (wobei Vererbung ohne Polymorphie eigentlich witzlos ist) lassen sich nicht wirklich nachbilden. Auch solche Dinge wie RAII sind in C unmöglich.
Zwischen OBP und OOP besteht immernoch ein Unterschied. Ja, OOP ist ein Konzept, aber das Konzept muss explizit vom Sprachumfang unterstützt werden.Und C++ unterstützt Reflection (@shade, ja, hier die "allgemein verstandene" Reflection ;)) nicht explizit. Also ist C++ nicht OOP sondern OBP? Java, objC und viele andere Sprachen kennen direkt keine Mehrfachvererbung, aber bieten Interfaces mit welchem man, mehr oder weniger, dasselbe macht...
Letzendlich führen solche Aussagen (von dir) zu Debatten darüber wie OOP definiert ist, ob es überhaupt definiert werden kann/soll. Das hatten wir schon oft hier. Ohne Konsens.
-
Ach und nochwas zu den C++ -> C Kompilern. Assembler ist dann eine hochsprache, weil C und C++ erst nach Assembler übersetzt werdne.
-
Tachyon schrieb:
OOP ist mit C nicht möglich. Punkt. Was man in C, und eigentlich so gut wie mit jeder imperativen Sprache machen kann, ist OBP.
Konzepte wie Polymorphie oder Vererbung (wobei Vererbung ohne Polymorphie eigentlich witzlos ist) lassen sich nicht wirklich nachbilden.dann schreibe dir flink eine vtable und ein paar makros für v-calls. dann hast zusammen mit dem, was ich oben für vererbung getippt habe, deine vererbung mit polymorphie (oben ist sie ja schon für datentypen) oder mach es gleich dynamisch. das geht. wenn du das ganze fertig haben willst: gobject. polymorphismus, vererbung, kapselung und hast du nicht gesehen. (ich finde den code zwar tierisch hässlich, aber das ist mein geschmack. ich mag auch vieles andere nicht, daher ist da hier nicht von relevanz.)
[quote="Tachyon"] Auch solche Dinge wie RAII sind in C unmöglich.[/cpp]
raii ist etwas, was es fast nur in c++ gibt. überall wo man keinen expliziten destruktor und/oder keine klare lebenszeiten (alle system mit gc...) für objekte hat, ist das nicht zu implementieren. wenn du es daran festmachen willst, sieht die welt der oop ziemlich dünn aus.Zwischen OBP und OOP besteht immernoch ein Unterschied. Ja, OOP ist ein Konzept, aber das Konzept muss explizit vom Sprachumfang unterstützt werden.
cool: dann ist c ja eine funktionalsprache, objektorientiert und logisch ist sie auch noch. tipp: c hat einen makropräprozessor. wenn du den wirklich benutzt, kriegst du zwar code, den kein schwein mehr versteht, aber damit ist quasi jedes sprachkonzept möglich.
-
ganzeinfach schrieb:
Sag ich doch. Hässliches gefrimel.
Datenkapselung geschieht doch in C++ zur Compilezeit, danach gibt es doch sowieso keine Möglichkeit mehr festzustellen, ob eine Methode public oder private war. Soviel zu den C++ -> C Kompilern.
den raffe ich jetzt nicht. ein c++->c compiler macht da genau das gleiche wie ein c++->asm oder c++->binary compiler er setzt zu dem zeitpunkt des kompilieren die forderungen um.
wenn ich jetzt an dem compiler vorbei spiele und bspw direkt auf die ausgabe bezug nehme, kann man die ganzen schutzmechanismen umgehen. es ist absolut kein kunststück die private oder protected funktionen eines objectes von außen aufzurufen, wenn man das ausgabemedium kennt.
-
ghorst schrieb:
den raffe ich jetzt nicht. ein c++->c compiler macht da genau das gleiche wie ein c++->asm oder c++->binary compiler er setzt zu dem zeitpunkt des kompilieren die forderungen um.
ja, und darum ist C noch lange keine OOP Sprache nur weil man alles was ein Kompiler mit OOP Sprache macht irgendwie nachbilden kann. Dann wären ja auch Assembler, Maschinencode und 0 und 1 OOP Sprachen.
Und die Datenkapselung in C ist nur solange gültig, wie die verwendeten Strukturen nicht Opensource sind (was sie im eigenen Programmen immer sind), den dann kann ich wieder ohne Probleme von außen auf internas der Struktur zugreifen.
-
wieso sollte ich in einem system das handles benutzt, die structs in einen header packen und damit für alle offen machen? in einer source datei untergebracht ist sie genauso sicher, wie die datenkapselung von c++... oder auch: wenn ich will, macht es keine mühe das zu unterlaufen. wenn ich mich an da interface halte, habe ich kein problem, auch wenn hinter der kulisse mal die implementierung getauscht wird. (letzteres ist übrigens einer hauptgründe, warum man datenkapselung überhaupt betreibt...)
ansonsten sie braucht nicht opensource sein. man kann so etwas auch reverse-engineeren. geht übrigens auch sowohl für c als auch c++. wenn du natürlich argumentierst, dass ich mich selber austricksen kann, muss ich dir recht geben. aber das kann ich in c++ auch.
-
Reverse engineering hat mal garnix damit zu tun ob ne Sprache OOP unterstützt oder nicht, das geht völlig am Thema vorbei.
Zeig mir einfach einen C Code bei dem ich allen Code sehen kann und der einen Compileerror erzeugt, weil ich auf interne Daten direkt zugreife.
-
ich zeige was viel schöneres: ein c++-code bei dem ich völlig legal die beschränkungen von protected und private umgehe.
#include <iostream> class foo{ public: foo(int a):m_a(a){} protected: virtual void dummy() {std::cout << "foo::dummy() " << m_a << std::endl;} private: int m_a; }; //nachbildung von foo als struct. das sollte mit den meisten c++-compiler funktionieren. struct foo_struct{ void **vtable; //das ist jetzt nicht ganz sauber, da es eigentlich funktionen //sind, aber passt scho, da man eh casten muss. int m_a; }; int main() { foo bar(12); foo_struct* bar_struct=(foo_struct*)(&bar); //einmal umgehen des private für daten-member std::cout << bar_struct->m_a << std::endl; //einmal aufruf einer protetcted funktion von außen void (*func_dummy)(foo) =(void (*)(foo))(*(bar_struct->vtable)); func_dummy(bar); }
alles was von der klasse wissen muss, ist wie sie aussieht. also genau das gleiche wie bei dem nachbilden der struct, die sich hinter einem handle verbirgt.
das von dir geforderte kann man nicht erstellen, da man spätestens, wenn man die bytes einzeln im speicher zusammensucht jeden schutzmechanismus umgehen kann. hier nehmen sich c++ und c nicht viel und auch viele andere programmiersprachen, die dynamische bindung unterstützen, nicht viel. mit genug liebe, ist alles möglich.
-
Tachyon schrieb:
OOP ist mit C nicht möglich. Punkt. Was man in C, und eigentlich so gut wie mit jeder imperativen Sprache machen kann, ist OBP.
Konzepte wie Polymorphie oder Vererbung (wobei Vererbung ohne Polymorphie eigentlich witzlos ist) lassen sich nicht wirklich nachbilden. Auch solche Dinge wie RAII sind in C unmöglich.
Zwischen OBP und OOP besteht immernoch ein Unterschied. Ja, OOP ist ein Konzept, aber das Konzept muss explizit vom Sprachumfang unterstützt werden.Hast du den verlinkten Artikel ueberhaupt selbst durchgelesen?
[...]Object-based languages that do not support inheritance or subtyping are usually not considered to be true object-oriented languages.
Niemand hat behauptet das C eine echte OOP-Sprache ist. In C kann man aber funktional, prozedurial und eben objektorientiert programmieren (OOP).
-
DEvent schrieb:
Niemand hat behauptet das C eine echte OOP-Sprache ist. In C kann man aber funktional, prozedurial und eben objektorientiert programmieren (OOP).
Genauso wie mit Assembler, ist halt nur ein gefrimel.
-
ganzeinfach schrieb:
Und die Datenkapselung in C ist nur solange gültig, wie die verwendeten Strukturen nicht Opensource sind (was sie im eigenen Programmen immer sind), den dann kann ich wieder ohne Probleme von außen auf internas der Struktur zugreifen.
Du definierst dir OOP wie es dir gefaellt. Sprachen wie zB Python oder JavaScript die man allgemeinhin als OO-Sprachen ansieht kennen auch keine Zugriffsrechte.
Das Problem ist, du definierst Kapselung ueber Zugriffsrechte. Das ist aber falsch. Zugriffsrechte helfen einem dabei Kapselung sicherer zu machen (gegen Murphy, nicht gegen machiavelli).
JavaScript hat zB keine Klassen und daher keine Vererbung und keine virtuellen Methoden. Dennoch hat es Polymorphie.
Aber wer wirklich zweifelt dass C OO-Programme unterstuetzt, der soll sich mal die WinAPI ansehen. Ueberall haben wir Handles auf denen wir operieren. Handles sind dabei polymorphe Objekte.
Wenn man mit der MFC programmiert hat, sollte einem das eigentlich klar geworden sein. Denn aus einem SetWindowTitle(hwnd, "text") wird ein this->SetTitle("text").
-
Ist das nicht eigentlich egal, ob C objektorientierte Programmierung unterstützt? Ich meine egal ist es nicht, weil ich persönlich für objektorientierte Programme c++ benutzen würde und das wohl vielen so geht.
Möglich ist es doch trotzdem sich ein Struct Namens "bla", Funktionen mit den Namen "bla_*****" zu erstellen und zu meinen: "Das ist jetzt meine Klasse bla und ich behandle sie wie eine Klasse und die Instanzen wie ein Objekt.
Ob jemand objektorientiert programmiert, liegt doch eher daran, wie er selbst sein Datenmüll interpretiert.
Was private/public angeht: Ich kann ja auch eine "Membervariable" mit dem Komentar "/*Achtung, privat!!!!!!*/" schützen. Klar, kann jemand ganz böses das ignorieren und auf die Variable zugreifen, aber dieser böse jemand kann auch in c++ mit ein paar Klicks mehr diese Variable in den public-Bereich verschieben - Das Ergebnis ist das selbe. Der einzige Unterschied ist, daß in c++ verhindert wird, aus Versehen auf eine geschützte Variable zuzugreifen. Da meckert der Kompiler. Das sehe ich aber eher als Komfortfunktion, die bei der Objektorientierten Programmierung hilft, nicht als "Erlaubnis" objektorientiert zu Programmieren.
In diesem Sinne: "Nein, du darfst nicht objektorientiert Programmieren, das ist C!"
-
So isses.
Ich habe den objektorientierten Ansatz auch mal probiert. Im Endeffekt sind so
viele Ausnahmen vom "Allgemeinen" aufgetreten das es eigentlich weder Zeit gespart
noch das Projekt übersichtlicher gemacht hat.OO ist keine Frage der Sprache, es ist eine Denke.
-
Ich muß gestehen, C++ als C mit Klassen zu mißbrauchen
und nach dem, was mir manchmal zur Nacharbeit unterkommt, scheint das im embedded- Bereich nicht unüblich zu sein. Ich nutze die Sprachfeatures von C++ also gar nicht bis im Sinne des Erfinders vermutlich unkorrekt.
Zu C (zurück)gekommen bin ich wegen der Kompatibilität auf Source- Ebene, da ist C unschlagbar!
OOP- Sachen nachzubilden ist natürlich machbar, gibt ja immer noch ein paar nette Precompiler, die Überladung, Vererbung usw. nachbilden. Ich hab's mir angeschaut, aber was da hinten rausfällt ist häßlich bis unwartbar- so ein bißchen tun wie OOP mach' ich auf Konzept- Ebene, der Code bleibt in C und ich werde belohnt, daß das Zeug für'n ATMega genauso compiliert wie für 'nen M16C, 'nen SH8 oder 'nem MSP430
.
Da ist C stark, macht Spaß
Aber echt OO ist das nicht, war dafür auch nicht gedacht, nur um zur root zurückzukommen ... also nicht echt OOP.
-
Ist euch eigentlich schon aufgefallen, daß es "OO" schon viel länger gibt wie "C" ?
Ich habe das erste Mal "OO" auf einer Tür mit einem Herzchen drin gesehen. Muß ein Dialekt sein ...
-
Der OP interpetiert klassen mit OOP, was auch soweit in ordnung ist. Und er hat gelesen das strukturen und Klassen in C++ das gleiche sind (soweit richtig auser die member Visibiliy). Nun denkt der OP um die ecke und glaub evtl. mit C auch OOP orientiert programmieren zu können. Nun das geht schon (wie gesaget ein Konzept). Allerdings muss man das OOP Konzept in C ohne diversen Sprachfeatures implementieren. Die ganze polymorphy Konstruktor, vererbung, konstruktor/destruktor memberfunktionen -> dinge gibts es nicht in C. Aber man kann dennoch einen OOP stil in C umsetzen bspw:
struct Person_Dat{ char acName[50]; int iAlter; }; Person_Dat* CreatePerson(char *acName,int iAlter){ Person_Dat* p=malloc(sizeof(Person_Dat)); strcpy(p->acName,acName); p->iAlter=iAlter; return p; } Person_Dat* CopyPerson(Person_Dat* p){ Person_Dat* pC=malloc(sizeof(Person_Dat)); memecpy(pC,p,sizeof(Person_Dat))); free(p); } void DelelePerson(Person_Dat* p){ free(p); }
etc.
-
DEvent schrieb:
Niemand hat behauptet das C eine echte OOP-Sprache ist. In C kann man aber funktional, prozedurial und eben objektorientiert programmieren (OOP).
Nein, man programmiert objektbasiert. Die Denke ist keine objektorientierte Denke, sondern eine objektbasierte Denke.
Das ist ein großer Unterschied, und die Ideen dafür wurden schon in den frühen 60'igern geboren.
Daraus ging dann auch recht schnell die erste objektorientierte Sprache hervor. Natürlich kann man jetzt wieder sagen, eine Unterscheidung zwischen objektbasiert und objektorientiert ist Korinthenkackerei, aber dann kann man auch sagen eine Unterscheidung zwischen Aggregation und Komposition ist Korinthenkackerei, oder sich diverse andere etablierte Begriffe heraussuchen und sagen, die geringen Unterschiede mit denen sich Begriff a) von Begriff b) unterscheidet sind Korinthenkackerei.
Btw. denke ich, Du hast den verlinkten Atikel nicht verstanden, denn Menge OBP > Menge OOP. :p
ghorst schrieb:
Dann schreibe dir flink eine vtable und ein paar makros für v-calls. dann hast zusammen mit dem, was ich oben für vererbung getippt habe, deine vererbung mit polymorphie (oben ist sie ja schon für datentypen) oder mach es gleich dynamisch. das geht. wenn du das ganze fertig haben willst: gobject. polymorphismus, vererbung, kapselung und hast du nicht gesehen. (ich finde den code zwar tierisch hässlich, aber das ist mein geschmack. ich mag auch vieles andere nicht, daher ist da hier nicht von relevanz.)
Mit Deinem Ansatz kann man nichtmal ein einfaches Aggregat vernünftig einfügen, ohne dafür eine Flut von Create-Funktionen aufzurufen. Und Du willst ja wohl nicht behaupten, dass der händische Aufruf einer Flut von spezialisierten Funktionen (spezialisiert, auf einzelne, bestimmte Strukturen) wirklich OOP sind, oder? Also: Eher nicht OOP.
@_sothis: Ja, lasst uns wieder alle ins Mittelalter sie Softwarekriese zurückfallen.
-
diese ganze konzeptflut und die daraus entstehenden diskussionen in der informatik sind korinthenkackerei
-
@tachyon ???
wieso sollte man damit nur schwer komposition/aggregation bauen können bzw. warum sollte es so schrecklich aufwendig sein? die "flut" von create-funktionen führst du bei c++/anderen oop sprachen auch aus. der einzige unterschied ist, dass sie bei c++ "klasse(parameter)" heißt und bei c mit oop "creatKlasse(parameter)". was daran nun soviel schwieriger oder aufwendiger sein soll, ist mir schleierhaft.oder hast du nicht verstanden, wie man die vtable + v-calls implementieren würde bzw. wie eine rein dynamische lösung aussehen würde?
-
ghorst schrieb:
@tachyon ???
wieso sollte man damit nur schwer komposition/aggregation bauen können bzw. warum sollte es so schrecklich aufwendig sein? die "flut" von create-funktionen führst du bei c++/anderen oop sprachen auch aus. der einzige unterschied ist, dass sie bei c++ "klasse(parameter)" heißt und bei c mit oop "creatKlasse(parameter)". was daran nun soviel schwieriger oder aufwendiger sein soll, ist mir schleierhaft.oder hast du nicht verstanden, wie man die vtable + v-calls implementieren würde?
Du musst Deine Creates für jedes Aggregat, für jede Vererbung usw. ausführen. Du willst doch nicht ernsthaft behaupten, dass Dein Funktionswust ein Ersatz dafür ist, was eine wirkliche OO-Sprache von Haus aus bietet.
Ich sehe in Deinen Funktionen nirgends OOP. Wenn überhaupt, dann vielleicht OBP, aber das kann man in C auch weniger unübersichtlich und fehlerträchtig hinbekommen.
Und was aufwändiger ist, sieht man alleine schon an Deinem katastophal unübersichtlichen Beispielkot.