c / expert
Snippet
Referenzgezähltes Objektmanagement mit dynamischen Destruktoren
Dieser Schnipsel konstruiert einen dynamischen Referenzzähl- und Destruktor-Header für C-Strukturen. Das Anfügen eines Destruktor-Funktionszeigers an eine Referenzzähler-Struktur ermöglicht eine automatisierte Lebensdauerverwaltung und saubere Zerstörung, sobald der Referenzzähler auf Null fällt.
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
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>#include <stdlib.h>typedef struct RefCounted RefCounted;typedef void (*DestructorFunc)(void* self);struct RefCounted {size_t ref_count;DestructorFunc dtor;};void ref_init(RefCounted* obj, DestructorFunc dtor) {obj->ref_count = 1;obj->dtor = dtor;}void ref_retain(RefCounted* obj) {if (obj) obj->ref_count++;}void ref_release(RefCounted* obj) {if (obj && --obj->ref_count == 0) {if (obj->dtor) obj->dtor(obj);}}typedef struct {RefCounted ref;int handle;} Resource;void resource_destroy(void* ptr) {Resource* res = (Resource*)ptr;printf("Closing resource handle %d\n", res->handle);free(res);}int main(void) {Resource* r = (Resource*)malloc(sizeof(Resource));ref_init(&r->ref, resource_destroy);r->handle = 42;ref_retain(&r->ref);ref_release(&r->ref);ref_release(&r->ref);return 0;}
Erklärung
1
struct RefCounted { size_t ref_count; DestructorFunc dtor; };
Enthält den Lebensdauer-Status einschließlich Referenzzähler und generischem Destruktor-Callback.
2
void ref_retain(RefCounted* obj) { if (obj) obj->ref_count++; }
Erhöht den internen Referenzzähler, um das Eigentum am Objekt über mehrere Referenzen zu teilen.
3
if (obj && --obj->ref_count == 0) { if (obj->dtor) obj->dtor(obj); }
Verringert den Zähler und löst bei Null-Referenzen automatisch den benutzerdefinierten Destruktor aus.
4
ref_init(&r->ref, resource_destroy);
Bindet die spezifische Zerstörungsfunktion an den eingebetteten Referenzverfolgungs-Header.