Skip to content

Instantly share code, notes, and snippets.

@TypeSafeSchwalbe
Created June 2, 2024 18:27
Show Gist options
  • Save TypeSafeSchwalbe/e792d80b364fe90c4bbf2207cda48ca0 to your computer and use it in GitHub Desktop.
Save TypeSafeSchwalbe/e792d80b364fe90c4bbf2207cda48ca0 to your computer and use it in GitHub Desktop.
// A small vtable example written in C.
// Enjoy :)
//// Interface definition ////
typedef struct {
void (*feed)(void* self, float amount);
} FeedableTable;
typedef struct {
FeedableTable* table;
void* value;
} Feedable;
//// Cat implementation ////
typedef struct {
int age;
float hunger;
} Cat;
void Cat_feed(Cat* self, float amount) {
self->hunger -= amount;
}
FeedableTable Cat_Feedable_table = (FeedableTable) {
.feed = (void (*)(void*, float)) &Cat_feed
};
//// Dog implementation ////
typedef struct {
unsigned long int playtime;
double volume;
} Dog;
void Dog_feed(Dog* self, float amount) {
self->volume -= amount / 2.0;
}
FeedableTable Dog_Feedable_table = (FeedableTable) {
.feed = (void (*)(void*, float)) &Dog_feed
};
//// Usage ////
void feed_dynamic(Feedable f, float amount) {
f.table->feed(f.value, amount);
}
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
srand(time(NULL));
Cat my_cat = (Cat) { .age = 5, .hunger = 0.5 };
Dog my_dog = (Dog) { .playtime = 1253, .volume = 2.0 };
Feedable my_feedable = rand() % 2 == 0
? (Feedable) {
.table = &Cat_Feedable_table,
.value = &my_cat
}
: (Feedable) {
.table = &Dog_Feedable_table,
.value = &my_dog
};
feed_dynamic(my_feedable, 0.3);
printf("my_cat.hunger = %f\n", my_cat.hunger); // prints '0.2' (if chosen) or '0.5'
printf("my_dog.volume = %f\n", my_dog.volume); // prints '1.85' (if chosen) or '2.0'
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment