Ich versuche gerade eine C++ Bibliothek in C umzuschreiben und stehe vor ein zwei Fragen. Soweit ich es verstanden habe handelt es sich bei diesem Konstrukt : "class foo : public bar" um das, was in C# einer vererbten Klasse entspricht. Das bedeutet die Klasse, Vererbung muß entfernt werden und die Funktionen werden als Prototypen in der zugehörigen Header Datei, entsprechend Public oder Private, veröffentlicht werden. Soweit so unklar, nur mit virtual und inline kann ich leider überhaupt nichts anfangen, wie würde man das übersetzen?
Virtuelle Funktionen in C++ funktionieren intern über Funktionszeiger. Viel Spaß beim nachbauen. Kann man machen, obs sinnvoll ist, musst du entscheiden. Oliver
Das sind doch nur ein paar Dutzend Zeilen. Lass virtual und inline einfach weg. Oliver
Die Basisklasse PN532Interface enthält nur 4 pure virtuelle Funktionen, da wird also nix vererbt. Einfach die #define aus PN532Interface.h in PN523_I2C.h kopieren und dann die Methoden als normale C-Funktionen schreiben, dann fluppt's. Aber warum würde man das machen?
Virtuelle Funktionen kann (nicht muss) eine abgeleitete Klasse überschreiben (durch seine eigene Variante ersetzen). Rein virtuelle Funktionen müssen von abgeleiteten Klassen überschrieben werden, weil sie abstrakt (ohne Code) sind. Inline hat eher etwas mit Performance-Optimierung zu tun, das kannst du erst mal außen vor lasen.
Stefan ⛄ F. schrieb: > Inline hat eher etwas mit Performance-Optimierung zu tun, das kannst du > erst mal außen vor lasen. Das stimmt so nicht, es kann zwar sein, dass der compiler eine inline Funktion eher inlined, aber dafür ist es nicht gedacht (vielleicht denkst du an das always_inline attribute vom gcc). Eine Funktion, die inline deklariert ist, kann in mehreren Object Files vorkommen, ohne einen Linker Fehler auszulösen, der Linker darf eine beliebige Implementierung verwenden. Also können inline Funktionen verwendet werden, um Code direkt im Header auszuprogrammieren. Bei den Funktionen hier ist ein sogar überflüssig, da in C++ Funktionen, die direkt in der Klassendeklaration ausprogrammiert werden, implizit immer inline sind.
Da gehört ja noch mehr dazu wie <Wire.h>, "Arduino.h". Evtl. ist es einfacher, extern "C" Wrapper zu schreiben, die dann von C aus aufgerufen werden? Zunächst generiert man Objekte per XXXnew was einem new XXX entspricht, und passt die Adresse zu allen XXXmethod die man braucht, und am Ende dann XXXdelete. Auf C-Ebene hat man dann nur einen void* oder einen Incomplete Type:
1 | typedef struct XXX; |
2 | |
3 | void func (param1_t p1, param2_t p2, ...) |
4 | {
|
5 | XXX *xxx = XXXnew (p1, p2, ); |
6 | XXXmethod (xxx, ...); |
7 | }
|
Wenn da eh Ardiuno drinhängt, dann must überlegen, wo die C/C++ Grenze verlaufen soll. Oder auch das ganze Ardiuno- und Wire-Zeugs portieren. Mit GCC kann man gemischte C/C++ projekte machen.
Alex D. schrieb: > vielleicht > denkst du an das always_inline attribute vom gcc Ja, das dachte ich tatsächlich. Danke für deine Erklärung.
ofront einer der ersten C++ kompiler überhaupt, war nichts anderes als ein "umschreiber" der C++ einlas und C generierte und dem normalen C kompiler übergab. Ab in die Mottenkiste wühlen gehen...
Stefan ⛄ F. schrieb: > Virtuelle Funktionen kann (nicht muss) eine abgeleitete Klasse > überschreiben (durch seine eigene Variante ersetzen). Das wäre völlig einfach nachzubauen, aber die bösen polymorphen Objekte bedürfen einer VMT. Jetzt wird 's in C sehr sehr aufwendig.
weiss alles schrieb: > aber die bösen polymorphen Objekte > bedürfen einer VMT. Jetzt wird 's in C sehr sehr aufwendig. Jepp. Zum Glück wird dieses Konstrukt nur selten benutzt.
Kompilerhistoriker schrieb: > ofront einer der ersten C++ kompiler überhaupt, war nichts anderes als > ein "umschreiber" der C++ einlas und C generierte und dem normalen C > kompiler übergab. > Ab in die Mottenkiste wühlen gehen... Es geht auch ganz modern: https://www.edg.com/c
Ich danke euch, aber so wird das nichts. Der Aufwand wird einfach viel zu groß. Beim ersetzen der Wire.h kam es auch noch zu Problemen, was dazu führt das die Arduino Bibliotheken ebenfalls verwendet werden müßten, das resultiert in einem riesigem Chaos. Das bedeutet es wird ein kleiner Extraprozessor mit dem C++ Code, der mit einfachen Befehlen über I2C gesteuert wird.
Holger L. schrieb: > Ich danke euch, aber so wird das nichts. Dann bleibe doch bei Arduino/C++ und nutzte nur das "C" in C++.
Stefan ⛄ F. schrieb: > Rein virtuelle Funktionen müssen von abgeleiteten Klassen überschrieben > werden, weil sie abstrakt (ohne Code) sind. Nein, nicht vorhandener Code kann auch nicht überschrieben werden. Vielleicht beschränkst du dich mal auf Themen, mit denen du dich auskennst? Keinem ist geholfen, wenn du mit jedem Posting 3 oder mehr Falschaussagen transportierst.
Stefan G. schrieb: > Nein, nicht vorhandener Code kann auch nicht überschrieben werden. Das ist Wortklauberei. > Keinem ist (damit) geholfen dass du andere herab würdigst. Das hier ist ein öffentliches Diskussionsforum von, mit und für Laien (ebenso wie Fachleuten), keine Bühne von der herab Professoren lehren. Wo sind denn deine hilfreichen Beiträge? Lass mich raten: Die hast du nicht hinter anonymen Namen versteckt, oder es gibt gar keine. Stimmt's?
Stefan G. schrieb: > Stefan ⛄ F. schrieb: >> Rein virtuelle Funktionen müssen von abgeleiteten Klassen überschrieben >> werden, weil sie abstrakt (ohne Code) sind. > > Nein, nicht vorhandener Code kann auch nicht überschrieben werden. Und dennoch wird empfohlen, in C++ eine solche "nicht-Überschreibung" mit dem Schlüsselwort override zu markieren.
Stefan ⛄ F. schrieb: > Zum Glück wird dieses Konstrukt nur selten benutzt. Hä, polymorphe Objekte sind mit das Wichtigste in OOP.
Alex D. schrieb: > Das stimmt so nicht, es kann zwar sein, dass der compiler eine inline > Funktion eher inlined, aber dafür ist es nicht gedacht (vielleicht > denkst du an das always_inline attribute vom gcc). Ich habe es bisher auch scheinbar falsch verstanden, und überdenke jetzt meine Nutzung. Was ich jedoch gefunden habe ist folgender Thread: https://stackoverflow.com/questions/22767523/what-inline-attribute-always-inline-means-in-the-function und vorallem das darin verlinkte Dokument: https://indico.cern.ch/event/386232/sessions/159923/attachments/771039/1057534/always_inline_performance.pdf Wenn ich es richtig verstehe, macht
1 | inlin
|
doch das, was es soll; oder?
Holger L. schrieb: > Ich danke euch, aber so wird das nichts. > Der Aufwand wird einfach viel zu groß. Beim ersetzen der Wire.h kam es > auch noch zu Problemen, was dazu führt das die Arduino Bibliotheken > ebenfalls verwendet werden müßten, das resultiert in einem riesigem > Chaos. Zieh die wichtigen Dinge aus den Code raus. Ich habe noch viel I2C Handling und "Betriebssystem" im Code gesehen.
Simon schrieb: > und vorallem das darin verlinkte Dokument: > > https://indico.cern.ch/event/386232/sessions/159923/attachments/771039/1057534/always_inline_performance.pdf > > Wenn ich es richtig verstehe, macht > inline > doch das, was es soll; oder? Das ist nur etwas verwirrend geschrieben. Eine Funktion als inline zu deklarieren ist nicht notwendig damit der Compiler diese inlined. Der große Unterschied hier ist, dass bei Verwendung von nur dem inline keyword der Compiler entscheiden kann, wann es Sinn ergibt eine Funktion zu inlinen. Eine inline Funktion ist nicht automatisch schneller, als ein Funktionsaufruf (besonders bei modernen CPUs), da es das Programm größer macht und eventuell große Auswirkungen auf die Effizienz der Caches haben kann (besonders wenn die gleiche Funktion oft in einer anderen Funktion aufgerufen wird, dann wird durch inlining der Code dupliziert). Man kann aber mit inline durchaus erreichen, dass der Compiler mehr Funktionen inlinen kann. Der Compiler kann nämlich nur Funktionen, deren Code er in der aktuellen Compilation Unit sehen kann, inlinen. Wenn der Körper der Funktion in einem separaten C-File programmiert ist, ist inlining (ohne LTO) nicht möglich. Also kann man Funktionen, die inlined werden sollen direkt als inline im Header deklarieren. Dadurch sieht der Compiler diese beim compilieren jeder .c Datei, die diesen Header inkludiert. Ohne __attribute__((always_inline)) entscheidet der Compiler aber darüber ob wirklich inlining betrieben wird.
weiss alles schrieb: >> Zum Glück wird dieses Konstrukt nur selten benutzt. > Hä, polymorphe Objekte sind mit das Wichtigste in OOP. Ja weiß ich, wird in der Realität trotzdem nur selten benutzt. Das ist ja mit einer der Punkte, wo viele Entwickler C++ für unnötig kompliziert halten. Google ist das sogar so ernst gewesen, dass sie eine eigene Programmiersprache (nämlich Go) entwickelten, die sie jetzt bevorzugt einsetzen, wo immer es geht.
Stefan ⛄ F. schrieb: > Ja weiß ich, wird in der Realität trotzdem nur selten benutzt. Fängste jetzt an durchzudrehen? Begriffswirrwarr in deinem Kopf? Bemerke: Du sprichst über Mehrfachvererbung. Sagst aber Polymorphie Tipp: Mehrfachvererbung und Polymorphie ist nicht das gleiche. ----------- Und dann kommt wieder so ein Schwank, aus dem Google Go Kiste, der nichts mit der Umsetzung von C++ Code zu C zu tun hat. Eine reine Nebelkerze.
Arduino Fanboy D. schrieb: > Stefan ⛄ F. schrieb: >> Ja weiß ich, wird in der Realität trotzdem nur selten benutzt. > > Fängste jetzt an durchzudrehen? > Begriffswirrwarr in deinem Kopf? > > Bemerke: > Du sprichst über Mehrfachvererbung. > Sagst aber Polymorphie Wo spricht denn hier wer von Mehrfachvererbung?
Wilhelm M. schrieb: > Wo spricht denn hier wer von Mehrfachvererbung? Der Stefan tut das: Stefan ⛄ F. schrieb: > Das ist ja mit einer der Punkte, wo viele Entwickler C++ für unnötig > kompliziert halten. Die Mehrfachvererbung, also das mehrfache (ver)erben von Implementierungen, hat in der Tat etwas "Widerwillen" erregt. Und damit steht C++ auch recht alleine. Andere Sprachen, wie z.B. ObjektPascal und Java, beschränken sich auf mehrfache Interfaces. Polymorphie dagegen, können alle OOP Sprachen, welche mir bekannt sind. (kenne aber nicht alle) Zumindest ist Polymorphie das täglich Brot eines C++ Programmierers. Und damit ist der folgende Satz schlich falsch! Stefan ⛄ F. schrieb: > Ja weiß ich, wird in der Realität trotzdem nur selten benutzt. Das fängt schon mit dem + Operator in C an. Der ist für alle Grund Datentypen vorhanden, incl. Pointer. Das ist schon Polymorphie. C++ geht da natürlich viel weiter, mit seiner Operatoren Überladung. Zu sagen, dass Polymorphie in C++ selten verwendet wird, halte ich für blanken Unsinn. Ganz im Gegenteil.
Alex D. schrieb: > Das ist nur etwas verwirrend geschrieben. Eine Funktion als inline zu > deklarieren ist nicht notwendig damit der Compiler diese inlined. > ... Vielen Dank!
Wilhelm M. schrieb: > Wo spricht denn hier wer von Mehrfachvererbung? Das habe ich mich auch gerade gefragt. Aber egal, ich habe keine Lust über Details von Programmiersprachen zu diskutieren. Ich werde dafür bezahlt, sie zu benutzen.
Arduino Fanboy D. schrieb: > Polymorphie dagegen, können alle OOP Sprachen, welche mir bekannt sind. > (kenne aber nicht alle) Schau dir mal Go an. Ich bin nicht sicher, ob diese überhaupt das Label "OOP" verdient - zumindest kann Go mit seinen Strukturen zugehörigen Methoden so etwas ähnliches. Aber ohne die Möglichkeit, sie zu überschrieben. > Zumindest ist Polymorphie das täglich Brot eines C++ Programmierers. Klar kommt man nicht darum herum. Aber wenn ich mir meine eigenen Programme ansehe, sind da nur wenige Klassen, die geerbte Methoden überschreiben. Was nichts daran ändert, dass man die meisten überschreiben könnte. Der indirekte Aufruf der Methoden über die VMT ist allgegenwärtig, wenn auch nicht direkt sichtbar. > Das fängt schon mit dem + Operator in C an. Operatorüberladung ist mir schon immer suspekt gewesen. Das ist sicher ein persönliches Ding. Vielleicht weil ich mit zahlreichen Programmiersprachen arbeiten muss, wo es das gar nicht gibt. Irgendwer sagte mal, dass meine C++ Programme auf den ersten Blick wie Java aussehen. :-) Stefan ⛄ F. schrieb: > ich habe keine Lust > über Details von Programmiersprachen zu diskutieren Misst, jetzt habe ich es doch getan. Langeweile versaut den Charakter.
Stefan ⛄ F. schrieb: > Aber ohne die Möglichkeit, sie zu überschrieben. Das ist nur eine Möglichkeit "Polymorphie" zu realisieren. C++ kennt da viele Möglichkeiten. Go noch nicht mal Vererbung. Go macht sich die "Polymorphie" über Interfaces. Also, zu sagen, dass es in Go kein "Polymorphie" gibt, ist falsch. Zudem ist es nur eine Nebelkerze. Den hier dreht es sich um, C++ Code in C wandeln. Da hilft der Vergleich mit Birnen überhaupt nicht. Weiterhin: Stefan ⛄ F. schrieb: > weiss alles schrieb: >>> Zum Glück wird dieses Konstrukt nur selten benutzt. >> Hä, polymorphe Objekte sind mit das Wichtigste in OOP. > > Ja weiß ich, wird in der Realität trotzdem nur selten benutzt. Das ist falsch! "Polymorphie" (in seinen unterschiedlichsten Ausprägungen) ist ein/der Dreh und Angelpunkt in C++. Da kann man drüber jammern, oder sich beschweren, aber es ist "täglich Brot"
Ist C++ eigentlich noch das Maß der Dinge, wenn wir von OOP reden, oder wird dieses Thema inzwischen von anderen Programmiersprachen angeführt? Alle Programmiersprachen die ich kenne unterstützen nur ein Subset von C++, deswegen halte ich C++ diesbezüglich für den "Anführer".
Irgendwelche "Anführer" sind mir egal. Mit der Projektion kann ich nix anfangen. Wenn du allergings meinst, dass C++ die vielseitigste Programmiersprache ist, magst du recht haben. Es unterstützt so ziemlich alle Paradigmen, welche je erfunden/definiert wurden. OPP ist nur eins dieser Paradigmen.
Arduino Fanboy D. schrieb: > Wilhelm M. schrieb: >> Wo spricht denn hier wer von Mehrfachvererbung? > > Der Stefan tut das: > Stefan ⛄ F. schrieb: >> Das ist ja mit einer der Punkte, wo viele Entwickler C++ für unnötig >> kompliziert halten. Sorry, ich habe es immer noch nicht gefunden ...
Wilhelm M. schrieb: >> Stefan ⛄ F. schrieb: >>> Das ist ja mit einer der Punkte, wo viele Entwickler C++ für unnötig >>> kompliziert halten. > > Sorry, ich habe es immer noch nicht gefunden ... Ist vermutlich Pluralis Majestatis ... Oliver
Wilhelm M. schrieb: > Sorry, ich habe es immer noch nicht gefunden .. Tja... Vielleicht habe ich ihn ja falsch verstanden... Dann frage mal unseren Stefen, was er damit meint, wenn er sagt, dass "Polymorphie" in C++ selten verwendet wird. Alternativ: Sage du mir doch mal bitte, ob du ihm in dem Punkt zustimmst.
Arduino Fanboy D. schrieb: > Dann frage mal unseren Stefen, was er damit meint, wenn er sagt, dass > "Polymorphie" in C++ selten verwendet wird. Jetzt verstehe ich Dich nicht: oben redest Du von Mehrfachvererbung, und nun allg. von Polymorphie. m was geht es Dir denn jetzt? Ich vermute auch, Du meinst im speziellen Inklusionspolymorphie, oder?
Stefan ⛄ F. schrieb: >> Hä, polymorphe Objekte sind mit das Wichtigste in OOP. > > Ja weiß ich, wird in der Realität trotzdem nur selten benutzt. Entsprich diese Aussage des Stefan wirklich der Realität?
Arduino Fanboy D. schrieb: >>> Hä, polymorphe Objekte sind mit das Wichtigste in OOP. >> Ja weiß ich, wird in der Realität trotzdem nur selten benutzt. > Entsprich diese Aussage des Stefan wirklich der Realität? Zumindest entspricht sie meiner Realität :-) So richtig sauber kann das wohl niemand bestätigen/abweisen, denn keiner kennt die ganze Welt. Aber Google ist schon mal eine Hausnummer, die halten es für überflüssig. Steht irgendwo in deren Doku zu Go.
Stefan ⛄ F. schrieb: > Zumindest entspricht sie meiner Realität :-) Deiner Projektion! Deiner Sichtweise. Die Realität kann es nur einmal geben. > Ja weiß ich, wird in der Realität trotzdem nur selten benutzt. Sage doch mal bitte etwas ausführlicher/konkreter, was du damit meinst.
Arduino Fanboy D. schrieb: > Stefan ⛄ F. schrieb: >>> Hä, polymorphe Objekte sind mit das Wichtigste in OOP. Das sicher nicht: OOP besteht aus Abstraktion, Kapselung, Polymorphie und Vererbung, wobei hier üblicherweise Inklusionspolymorphie gemeint ist. "Polymorphe Objekte" gibt es nicht, der Begriff ist falsch, denn ein Objekte ist eine Entität mit einem Wert und genau einem Datentyp. Polymorphie ist also etwas Wichtiges in der OOP, aber sicher nicht DAS wichtigste. Abstraktion und Kapselung ist m.E. wichtiger. >> >> Ja weiß ich, wird in der Realität trotzdem nur selten benutzt. > Entsprich diese Aussage des Stefan wirklich der Realität? Bezogen auf eine Multiparadigmensprache wie C++ kann man so nicht sagen, denn das zu lösende Problem bestimmt das Programmierparadigma. Allerdings sind die Zeiten des Inheritance-Overkills aus den Anfangstagen der OOP vorbei, wenngleich viele Anfänger diesen Fehler immer noch machen. Exzessive Vererbung führt zu enger Koppelung. Deswegen sollte man Komposition (und Aggregation) der Vererbung vorziehen.
Arduino Fanboy D. schrieb: > Sage doch mal bitte etwas ausführlicher/konkreter, was du damit meinst. Ich meine, dass man nur selten Methoden von Objekten in deren Nachfahren (abgeleitete Objekte) überschreibt.
Überschreiben ist doch nur eine kleine Facette der Polymorphie. Mag schon sein, dass das seltener ist... Überladen von Methoden gehört auch zur Polymorphie, und ist weit häufiger anzutreffen. Und damit ist Polymorphie als solches schon nicht mehr selten.
Ihr redet permanent aneinander vorbei, weil keiner von Euch beiden in der Lage ist, die korrekten Begriffe zu verwenden. Erst heißt es bei einem Mehrfachvererbung, dann ist aber insgesamt Polymorphie gemeint, der andere versteht darunter nur Inklusionspolymorphie, der nä. meint Überladung und vllt. kommt ja noch einer mit ad-hoc-Polymorphie um die Ecke.
Arduino Fanboy D. schrieb: > Überschreiben ist doch nur eine kleine Facette der Polymorphie. Ich habe weder das Wort "Polymorphie" noch "Mehrfachvererbung" verwendet. Der Stein des Anstoßes war: Stefan ⛄ F. schrieb: > Virtuelle Funktionen kann (nicht muss) eine abgeleitete Klasse > überschreiben (durch seine eigene Variante ersetzen). weiss alles schrieb: > Das wäre völlig einfach nachzubauen, aber die bösen polymorphen Objekte > bedürfen einer VMT. Jetzt wird 's in C sehr sehr aufwendig. Stefan ⛄ F. schrieb: > Jepp. Zum Glück wird dieses Konstrukt nur selten benutzt. "Dieses Konstrukt" ist das Überschreiben geerbter Methoden. Anders war es von mir nie gemeint.
Wilhelm M. schrieb: > vllt. kommt ja noch einer mit ad-hoc-Polymorphie um die > Ecke. Habe ich doch gerade! > überladen Das ist das doch, oder?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.