c / expert
Snippet
Virtual-Dispatch-Tabelle zur Erreichung von Schnittstellen-Polymorphismus
Dort wird die explizite Erstellung einer virtuellen Funktionstabelle (VTable) in ISO C demonstriert. Indem ein Zeiger auf eine Struktur aus Funktionszeigern (`vptr`) am Anfang einer Basisstruktur platziert wird, wird dynamisches Dispatching durch direkte Dereferenzierung ohne Laufzeit-Typüberprüfungen erreicht.
snippet.c
c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>typedef struct Shape Shape;typedef struct {double (*area)(const Shape* self);} ShapeVTable;struct Shape {const ShapeVTable* vptr;};typedef struct {Shape base;double radius;} Circle;static double circle_area(const Shape* self) {const Circle* c = (const Circle*)self;return 3.1415926535 * c->radius * c->radius;}static const ShapeVTable circle_vtable = { .area = circle_area };void circle_init(Circle* c, double r) {c->base.vptr = &circle_vtable;c->radius = r;}int main(void) {Circle c;circle_init(&c, 5.0);Shape* s = (Shape*)&c;printf("Area: %f\n", s->vptr->area(s));return 0;}
Erklärung
1
typedef struct { double (*area)(const Shape* self); } ShapeVTable;
Definiert die Tabelle der Schnittstellen-Funktionszeiger (VTable), passend zu den Methodensignaturen.
2
struct Shape { const ShapeVTable* vptr; };
Bettet den VTable-Zeiger als erstes Element des Basistyps ein, um polymorphes Casting zu ermöglichen.
3
static const ShapeVTable circle_vtable = { .area = circle_area };
Erstellt eine statische, konstante Instanz der VTable für die konkrete Circle-Implementierung.
4
s->vptr->area(s)
Ruft die polymorphe Funktion über VTable-Zeiger-Dereferenzierung mit expliziter Bindung von self auf.