c / expert
Snippet
Polymorphe Subtypisierung mit Einzelvererbung durch Struct-Einbettung
Der C-Standard garantiert, dass die Adresse einer Struktur mit der Adresse ihres ersten Elements übereinstimmt. Durch das Einbetten einer Basis-Struktur als erstes Feld einer abgeleiteten Struktur können Instanzen sicher in Basis-Zeiger konvertiert werden. Zusammen mit Zeigern auf virtuelle Funktionstabellen ermöglicht diese Eigenschaft objektorientierte Subtypisierung mit Einzelvererbung in reinem C.
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
#include <stdio.h>typedef struct Shape Shape;struct ShapeVtable {double (*area)(const Shape *self);};struct Shape {const struct ShapeVtable *vptr;};typedef struct {Shape base;double radius;} Circle;double circle_area(const Shape *self) {const Circle *c = (const Circle *)self;return 3.14159 * c->radius * c->radius;}static const struct 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 = &c.base;printf("Area: %.2f\n", s->vptr->area(s));return 0;}
Erklärung
1
Shape base;
Bettet die Basis-Struktur an Offset Null ein für sichere Konvertierung von Zeigern.
2
c->base.vptr = &circle_vtable;
Weist dem vptr-Feld des Basisobjekts die kreisspezifische virtuelle Funktionstabelle zu.
3
s->vptr->area(s)
Ruft die virtuelle Flächenberechnung indirekt über den Zeiger auf und übergibt die Basisreferenz.