Welche Techniken / Strategien verwenden Menschen zum Erstellen von Objekten in C (nicht C ++)?

7

Ich bin besonders an Objekten interessiert, die aus C heraus verwendet werden sollen, im Gegensatz zu Implementierungen von Objekten, die den Kern von interpretierten Sprachen wie Python bilden.

    
SetJmp 04.08.2009, 05:48
quelle

6 Antworten

9

Ich tendiere dazu, so etwas zu tun:

%Vor%

Mit diesen Strukturdefinitionen sieht der Code, der foo implementiert, ungefähr so ​​aus:

%Vor%

Dann in Code, der foo verwendet:

%Vor%

Dieser Code kann mit Makros oder Inline-Funktionen aufgeräumt werden, sodass er mehr C-ähnlich aussieht

%Vor%

Wenn Sie jedoch mit einem relativ kurzen Namen für das Feld "ops" bleiben, ist es einfach nicht besonders ausführlich, den ursprünglich angezeigten Code auszugeben.

Diese Technik ist völlig ausreichend, um ein relativ einfaches objektbasiertes Design in C zu implementieren, aber nicht kann komplexere Anforderungen wie das explizite Darstellen von Klassen und die Vererbung von Methoden verarbeiten. Für diese benötigen Sie möglicherweise etwas wie GObject (wie EFraim erwähnt), aber ich würde vorschlagen, sicherzustellen, dass Sie wirklich die zusätzlichen Funktionen der komplexeren Frameworks benötigen.

    
Dale Hagglund 04.08.2009 07:05
quelle
7

Ihr Gebrauch des Begriffs "Objekte" ist ein bisschen vage, also gehe ich davon aus, dass Sie fragen, wie Sie mit C bestimmte Aspekte der objektorientierten Programmierung erreichen können (fühlen Sie sich frei, mich unter dieser Annahme zu korrigieren). )

Methodenpolymorphie:

Methodenpolymorphie wird typischerweise in C mit Funktionszeigern emuliert. Wenn ich zum Beispiel eine Struktur hätte, die ich für einen image_scaler verwende (etwas, das ein Bild aufnimmt und es auf neue Dimensionen anpasst), könnte ich Folgendes tun:

%Vor%

Dann könnte ich mehrere Bildskalierer als solche machen:

%Vor%

Dies ermöglicht es mir, polymorphes Verhalten für jede Funktion zu erreichen, die einen Bildskalierer aufnimmt und seine Skalierungsmethode verwendet, indem sie einfach einen anderen Bildskalierer übergeben.

Vererbung

Die Vererbung wird normalerweise als solche erreicht:

%Vor%

Nun kann ich die zusätzlichen Felder von abgeleiteten Feldern zusammen mit allen geerbten Feldern der Basis verwenden. Wenn Sie eine Funktion haben, die nur eine Strukturbasis einnimmt. Sie können Ihren struct-dervied-Zeiger einfach in einen struct-Basiszeiger ohne Konsequenzen umwandeln

    
Falaina 04.08.2009 07:39
quelle
4

Bibliotheken wie GObject .

GObject bietet im Allgemeinen die Möglichkeit, undurchsichtige Werte (Integer, Strings) und Objekte zu beschreiben (durch manuelle Beschreibung der Schnittstelle - als eine Struktur von Funktionszeigern, die im Wesentlichen einer VTabelle in C ++ entspricht) - mehr Informationen über die Struktur in seiner Referenz

Sie würden oft auch vtables wie in "COM in plain C" manuell implementieren

>     
EFraim 04.08.2009 05:50
quelle
2

Wie Sie sehen können, wenn Sie alle Antworten durchsuchen, gibt es Bibliotheken, Funktionszeiger, Mittel zur Vererbung, Verkapselung usw., alle verfügbar (C ++ war ursprünglich ein Front-End für C).

Ich habe jedoch festgestellt, dass ein SEHR wichtiger Aspekt der Software ist Lesbarkeit. Haben Sie versucht, Code von vor 10 Jahren zu lesen? Als ein Ergebnis, neige ich dazu, den einfachsten Ansatz zu nehmen, wenn ich Dinge wie Objekte in C.

Fragen Sie Folgendes:

  1. Ist dies für einen Kunden mit einer Frist (wenn ja, in Betracht ziehen OOP)?
  2. Kann ich ein OOP verwenden (oft weniger Code, schneller zu entwickeln, lesbarer)?
  3. Kann ich eine Bibliothek verwenden (vorhandenen Code, vorhandene Vorlagen)?
  4. Bin ich durch Speicher oder CPU (zum Beispiel Arduino) eingeschränkt?
  5. Gibt es einen anderen technischen Grund, C zu benutzen?
  6. Kann ich mein C sehr einfach und lesbar halten?
  7. Welche OOP-Funktionen brauche ich wirklich für mein Projekt?

Ich gehe normalerweise auf etwas wie die GLIB API zurück, die mir erlaubt kapseln meinen Code ein und stellen eine sehr lesbare Schnittstelle zur Verfügung. Wenn mehr ist erforderlich, ich füge Funktionszeiger für Polymorphismus hinzu.

%Vor%     
Wadester 14.08.2013 17:22
quelle
0

Sehen Sie sich die IJG Implementierung an. Sie verwenden nicht nur setjmp / longjmp für die Ausnahmebehandlung, sie haben vtables und alles. Es ist eine gut geschriebene und klein genug Bibliothek für Sie, um ein sehr gutes Beispiel zu bekommen.

    
cheez 04.08.2009 05:50
quelle
0

Ähnlich wie Dales Ansatz, aber etwas mehr von einer Fußfeuerwaffe, stellt PostgreSQL intern Syntaxknoten, Ausdruckstypen und dergleichen dar. Es gibt die Standardwerte Node und Expr structs in den Zeilen von

%Vor%

Dabei ist NodeTag ein Typdef für unsigned int, und es gibt eine Headerdatei mit einer Reihe von Konstanten, die alle möglichen Knotentypen beschreiben. Knoten selbst sehen so aus:

%Vor%

und ein FooNode können wegen einer Eigenart von C-Strukturen ungestraft in ein Node umgewandelt werden: Wenn zwei Strukturen identische erste Elemente haben, können sie ineinander umgewandelt werden.

Ja, das bedeutet, dass FooNode in BarNode umgewandelt werden kann, was Sie wahrscheinlich nicht tun möchten. Wenn Sie eine korrekte Laufzeitprüfung wünschen, ist GObject der richtige Weg. Seien Sie jedoch darauf vorbereitet, das Leben zu hassen, während Sie den Dreh raushaben.

(Hinweis: Beispiele aus dem Speicher, ich habe die Postgres-Interna seit einiger Zeit nicht mehr gehackt. Die Entwickler-FAQ hat mehr Info.)

    
Meredith L. Patterson 04.08.2009 18:01
quelle

Tags und Links