Objektorientierte Programmierung in C [duplicate]

Lesezeit: 9 Minuten

Benutzeravatar von Chinmay Kanchi
Chinmay Kanchi

Mögliche Duplikate:

Können Sie objektorientierten Code in C schreiben?
Objektorientiertes Muster in C?

Ich erinnere mich, dass ich vor einiger Zeit von jemandem gelesen habe (ich glaube, es war Linus Torvalds), der darüber sprach, dass C++ eine schreckliche Sprache ist und wie man objektorientierte Programme mit C schreiben kann. Nachdem ich Zeit zum Nachdenken hatte, verstehe ich nicht wirklich, wie alle objektorientierte Konzepte werden in C übernommen. Einige Dinge sind ziemlich offensichtlich. Zum Beispiel:

  1. Um Elementfunktionen zu emulieren, können Sie Funktionszeiger in Strukturen einfügen.
  2. Um Polymorphismus zu emulieren, können Sie eine Funktion schreiben, die eine variable Anzahl von Argumenten akzeptiert und abhängig von, sagen wir, ein bisschen Voodoo macht sizeof Die Parameter)

Wie würden Sie Kapselung und Vererbung emulieren?

Ich nehme an, die Kapselung könnte irgendwie emuliert werden, indem man eine verschachtelte Struktur hat, die private Mitglieder speichert. Es wäre ziemlich einfach zu umgehen, könnte aber vielleicht benannt werden PRIVATE oder etwas ebenso Offensichtliches, um zu signalisieren, dass es nicht von außerhalb der Struktur verwendet werden soll. Aber was ist mit dem Erbe?

  • Es ist ziemlich böse IMO. Deshalb haben wir höhere Sprachen.

    – ChaosPandion

    2. Februar 2010 um 0:27 Uhr

  • Duplikate: stackoverflow.com/questions/351733?tab=votes#tab-top, stackoverflow.com/questions/1201521/…

    – Chris Lutz

    2. Februar 2010 um 0:28 Uhr

  • Schwerwiegender Missbrauch von Stackoverflow für die Online-Profilerstellung. Warum zum Teufel will das jemand machen??.

    – A_Var

    24. Dezember 2010 um 22:39 Uhr

  • Ich habe diesen ganzen Thread gelesen und … ähm … na ja … Wissen die Leute nicht, dass C eine Sprachunterstützung für die private Kapselung von Variablen und Funktionen durch das Schlüsselwort static hat? Dies wurde nicht erwähnt, obwohl es für C-Programmierer sehr grundlegendes Wissen ist, OO hin oder her. Ich gehe davon aus, dass Sie alle dachten, dass die Verwendung des Schlüsselworts static für die Kapselung so grundlegend ist, dass Sie sich nicht einmal die Mühe gemacht haben, es zu erwähnen. Recht?

    – Ludin

    4. Februar 2011 um 13:37 Uhr

  • So-o (einfach objektorientiert) – so-o.org – definiert eine Funktionsschicht, die einer strukturierten Programmiersprache ein objektorientiertes Programmiermodell hinzufügt. Inspiriert von Smalltalk und Objective C ist So-o vollständig, einfach und leicht, leicht zu verstehen. Die Implementierung in C umfasst etwa 1500 Codezeilen. So-o hat 3 Funktionen: defclass, das eine neue Klasse definiert, sendmsg, das systematisch verwendet wird, um eine Nachricht an eine Klasse oder eine Instanz zu senden, und supersend, das eine von einer Oberklasse geerbte Methode ausführt.

    – frasq

    27. Juli 2018 um 18:35 Uhr

Benutzeravatar von Tronic
Tronik

Sie können Polymorphismus mit regulären Funktionen und virtuellen Tabellen (vtables) implementieren. Hier ist ein ziemlich nettes System, das ich (basierend auf C++) für eine Programmierübung erfunden habe: Alt-Text

Die Konstruktoren weisen Speicher zu und rufen dann die Init-Funktion der Klasse auf, wo der Speicher initialisiert wird. Jede Init-Funktion sollte auch eine statische vtable-Struktur enthalten, die die virtuellen Funktionszeiger enthält (NULL für rein virtuell). Abgeleitete Klassen-Init-Funktionen rufen die Superklassen-Init-Funktion auf, bevor sie irgendetwas anderes tun.

Eine sehr schöne API kann erstellt werden, indem die virtuellen Funktionswrapper (nicht zu verwechseln mit den Funktionen, auf die die vtables zeigen) wie folgt implementiert werden (add static inline davor, wenn Sie dies in der Kopfzeile tun):

int playerGuess(Player* this) { return this->vtable->guess(this); }

Einfache Vererbung kann durch Missbrauch des binären Layouts einer Struktur erfolgen: Alt-Text

Beachten Sie, dass die Mehrfachvererbung chaotischer ist, da Sie dann häufig den Zeigerwert anpassen müssen, wenn Sie zwischen den Typen der Hierarchie umwandeln.

Den virtuellen Tabellen können auch andere typspezifische Daten hinzugefügt werden. Beispiele hierfür sind Informationen zum Laufzeittyp (z. B. Typname als Zeichenfolge), die Verknüpfung mit der vtable der Superklasse und die Destruktorkette. Sie möchten wahrscheinlich virtuelle Destruktoren, bei denen der Destruktor der abgeleiteten Klasse das Objekt zu seiner Superklasse herabstuft und dann rekursiv den Destruktor davon aufruft und so weiter, bis der Destruktor der Basisklasse erreicht ist und die Struktur schließlich freigegeben wird.

Verkapselung wurde durch Definieren der Strukturen in player_protected.h und Implementieren der Funktionen (auf die vtable zeigt) in player_protected.c und ähnlich für abgeleitete Klassen durchgeführt, aber das ist ziemlich umständlich und verschlechtert die Leistung (da virtuelle Wrapper nicht in Header eingefügt werden können ), also würde ich davon abraten.

  • +1 für die hübschen Bilder.

    – Präsident James K. Polk

    2. Februar 2010 um 2:18 Uhr

  • @Tronic – Ich bin mir nicht sicher, ob Sie ein Java-Typ sind, aber die Art und Weise, wie die HotSpot-JVM OO implementiert, ist dieser sehr ähnlich. Natürlich ist Java für die Implementierung einfach vererbt, also löst dies das Problem der Mehrfachvererbung. Ich muss vielleicht C/C++-Leute hierher verweisen, wenn ich ihnen in Zukunft Java / JVM OO erklären muss.

    – Miezekatze

    1. Dezember 2011 um 1:44 Uhr

  • C++ implementiert OOP auch so.

    – Tronik

    13. November 2012 um 10:08 Uhr

  • Mehrfachvererbung – ein besonders abscheulicher und unnötiger Code-Gestank. Komposition? Mit allen Mitteln.

    – Techniker

    10. November 2015 um 15:32 Uhr

Hast du die “Bibel” zu diesem Thema gelesen? Sehen Objektorientiertes C

  • @tur1ng – aus Versehen – ich habe die PDF-Erweiterung in Chrome installiert :>

    – Kornel Kisielewicz

    2. Februar 2010 um 0:44 Uhr

  • Danke für den Beitrag. Wie heißt der nächste und Autor? Es ist nicht in der Datei aufgeführt.

    – Benutzer1527227

    17. April 2014 um 9:01 Uhr

Benutzeravatar von John Knöller
Johannes Knöller

Wie würden Sie Kapselung und Vererbung emulieren?

Tatsächlich ist die Kapselung der einfachste Teil. Kapselung ist eine Entwurf Philosophie hat überhaupt nichts mit der Sprache zu tun, sondern alles damit, wie Sie über Probleme denken.

Beispielsweise ist die Windows FILE-API vollständig gekapselt. Wenn Sie eine Datei öffnen, erhalten Sie ein undurchsichtiges Objekt zurück, das alle Statusinformationen für das „Objekt“ der Datei enthält. Sie geben dieses Handle an jede der Datei io apis zurück. Die Kapselung ist tatsächlich viel besser als C++, da es keine öffentliche Header-Datei gibt, die die Leute einsehen und die Namen Ihrer privaten Variablen sehen können.

Vererbung ist schwieriger, aber überhaupt nicht notwendig, damit Ihr Code objektorientiert ist. In mancher Hinsicht ist Aggregation ohnehin besser als Vererbung, und Aggregation ist in C genauso einfach wie in C++. sehen Dies zum Beispiel.

Als Antwort auf Neil see Wikipedia für eine Erklärung, warum Vererbung für Polymorphismus nicht notwendig ist.

Wir Oldtimer haben objektorientierten Code geschrieben, Jahre bevor C++-Compiler verfügbar waren, es ist eine Denkweise, kein Werkzeugsatz.

  • Wenn Sie keine Vererbung haben, haben Sie keinen Laufzeitpolymorphismus und Sie haben kein OO.

    anon

    2. Februar 2010 um 0:49 Uhr

  • @Neil: Ich sehe nicht, dass du oft Fehler machst, aber in diesem Punkt liegst du völlig falsch. Erbe ist nicht a notwendig Merkmal von OO. Sie können Polymorphismus durch Aggregation/Delegation erhalten.

    – Johannes Knöller

    2. Februar 2010 um 1:06 Uhr


  • Sie würden Ada83 nicht als objektorientiert betrachten, aber es hat alle Funktionen außer Vererbung und Polymorphismus. Ich stimme Neil zu. Etwas anderes zu sagen, bedeutet, den gesamten Zweck, für den das OOP-Paradigma erfunden wurde, vollständig aufzugeben: die Wiederverwendung von Code.

    – San Jacinto

    2. Februar 2010 um 1:42 Uhr


  • Das am häufigsten wiederverwendete Codestück aller Zeiten ist das Standard c-Laufzeitbibliothek, obwohl der meiste C++-Code tatsächlich viral ist, können Sie nicht nur einen Teil davon verwenden, ohne die ganze Enchalada einzusaugen.

    – Johannes Knöller

    2. Februar 2010 um 1:51 Uhr


  • @San Jacinto: Es ist durchaus möglich, OO-Code in ADA zu schreiben, aber nein, betrachten Sie es nicht als OO-Sprache. Ich betrachte C++ auch nicht als OO-Sprache – zu viel Leckage aus den Wurzeln der Systemprogrammierung.

    – Johannes Knöller

    2. Februar 2010 um 2:39 Uhr

Apples C-basiertes CoreFoundation-Framework wurde eigentlich so geschrieben, dass seine „Objekte“ als Objekte in Objective-C, einer echten OO-Sprache, dienen können. Eine ziemlich große Teilmenge des Frameworks ist auf Apples Website als Open Source verfügbar CF-Lite. Könnte eine nützliche Fallstudie in einem großen Framework auf Betriebssystemebene sein, das auf diese Weise durchgeführt wird.

Aus etwas größerer Höhe und etwas aufgeschlossener gegenüber dem Problem, als es der OOP-Mainstream vermuten lässt, bedeutet objektorientierte Programmierung, Objekte als Daten mit zugehörigen Funktionen zu betrachten. Dies bedeutet nicht unbedingt, dass eine Funktion physisch an ein Objekt angehängt werden muss, wie dies in gängigen Sprachen der Fall ist, die das OOP-Paradigma unterstützen, beispielsweise in C++:

struct T
{
   int data;
   int get_data() const { return data; }
};

Ich würde vorschlagen, sich das genauer anzusehen GTK+ Objekt- und Typensystem. Es ist ein brillantes Beispiel für OOP, das in der Programmiersprache C realisiert wurde:

GTK+ implementiert sein eigenes benutzerdefiniertes Objektsystem, das objektorientierte Standardfunktionen wie Vererbung und virtuelle Funktion bietet

Die Verbindung kann auch vertraglich und konventionell sein.

In Bezug auf Kapselungs- und Datenverstecktechniken mag eine beliebt und einfach sein Undurchsichtiger Zeiger (oder undurchsichtiger Datentyp) – Sie können ihn herumreichen, aber um Informationen zu laden oder zu speichern, müssen Sie die zugehörige Funktion aufrufen, die weiß, wie sie mit dem hinter diesem undurchsichtigen Zeiger verborgenen Objekt kommunizieren kann.

Eine andere, ähnlich, aber anders ist Shadow-Datentyp – überprüfen Sie diesen Link wo Jon Jäger gibt eine hervorragende Erklärung dieser nicht so bekannten Technik.

  • Wie also implementiert man Schnittstellen, ohne tatsächlich Methoden an das Objekt anzuhängen? Ich denke, Ihr undurchsichtiger Zeiger könnte dies ansprechen, aber ich verstehe nicht, wie ohne ein Beispiel. Die Programmiersprache Go teilt Ihre sehr generische Philosophie über OOP, aber sie war immer noch gezwungen, das Anhängen von Methoden an Typen zuzulassen, um Schnittstellen zu erleichtern.

    – weberc2

    7. Juli 2014 um 15:59 Uhr


Benutzeravatar von Chris H
Chris H

Die gtk- und glib-Bibliotheken verwenden Makros, um Objekte in verschiedene Typen umzuwandeln.
add_widget(GTK_WIDGET(myButton));
Ich kann nicht sagen, wie es gemacht wird, aber Sie können ihre Quelle lesen, um genau herauszufinden, wie es gemacht wird.

  • Wie also implementiert man Schnittstellen, ohne tatsächlich Methoden an das Objekt anzuhängen? Ich denke, Ihr undurchsichtiger Zeiger könnte dies ansprechen, aber ich verstehe nicht, wie ohne ein Beispiel. Die Programmiersprache Go teilt Ihre sehr generische Philosophie über OOP, aber sie war immer noch gezwungen, das Anhängen von Methoden an Typen zuzulassen, um Schnittstellen zu erleichtern.

    – weberc2

    7. Juli 2014 um 15:59 Uhr


Benutzeravatar von caf
Café

Werfen Sie einen Blick auf die Funktionsweise der VFS-Schicht im Linux-Kernel, um ein Beispiel für ein Vererbungsmuster zu erhalten. Die Dateioperationen für die verschiedenen Dateisysteme “erben” einen Satz generischer Dateioperationsfunktionen (z generic_file_aio_read(), generic_file_llseek()…), können sie aber mit ihren eigenen Implementierungen überschreiben (z. ntfs_file_aio_write()).

1411660cookie-checkObjektorientierte Programmierung in C [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy