c / expert
Snippet
Abstrakte Schnittstellen-Verteilung über VTable-Struktur-Zeiger
Dieses Beispiel demonstriert objektorientierte Polymorphie in reinem C unter Verwendung von virtuellen Methodentabellen (VTables). Eine abstrakte Basis-Struktur enthält einen Zeiger auf eine Struktur aus Funktionszeigern (die VTable). Konkrete Implementierungen betten die Basis-Struktur ein und weisen deren VTable-Member auf eine statisch definierte Tabelle von konkreten Callback-Funktionen zu, um dynamische Aufrufe ohne Speicher-Overhead zu ermöglichen.
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 LoggerVTable LoggerVTable;typedef struct {const LoggerVTable *vtable;} Logger;struct LoggerVTable {void (*log)(Logger *self, const char *msg);};typedef struct {Logger base;const char *prefix;} ConsoleLogger;static void console_log_impl(Logger *self, const char *msg) {ConsoleLogger *cl = (ConsoleLogger *)self;printf("[%s] %s\n", cl->prefix, msg);}static const LoggerVTable CONSOLE_LOGGER_VTABLE = {.log = console_log_impl};void console_logger_init(ConsoleLogger *cl, const char *prefix) {cl->base.vtable = &CONSOLE_LOGGER_VTABLE;cl->prefix = prefix;}void logger_dispatch(Logger *logger, const char *msg) {if (logger && logger->vtable && logger->vtable->log) {logger->vtable->log(logger, msg);}}
Erklärung
1
struct LoggerVTable {
Definiert das Layout der virtuellen Tabelle mit Funktionszeigern für Schnittstellenmethoden.
2
void (*log)(Logger *self, const char *msg);
Deklariert einen Funktionszeiger, der die explizite 'self'-Instanzreferenz empfängt.
3
ConsoleLogger *cl = (ConsoleLogger *)self;
Führt einen Downcast des Basis-Zeigers auf den abgeleiteten Typ durch, um auf den Status zuzugreifen.
4
cl->base.vtable = &CONSOLE_LOGGER_VTABLE;
Verknüpft den Zeiger der virtuellen Tabelle bei der Initialisierung mit der statischen Sprungtabelle.
5
logger->vtable->log(logger, msg);
Führt die dynamische Aufruf-Verteilung durch Dereferenzierung der Methode aus der VTable aus.